LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KICogICAgICAgICBBVE1FTCBNaWNyb2NvbnRyb2xsZXIgU29mdHdhcmUgU3VwcG9ydA0KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KICogQ29weXJpZ2h0IChjKSAyMDEwLCBBdG1lbCBDb3Jwb3JhdGlvbg0KICoNCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQogKg0KICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0DQogKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoNCiAqDQogKiAtIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwNCiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZGlzY2xhaW1lciBiZWxvdy4NCiAqDQogKiBBdG1lbCdzIG5hbWUgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20NCiAqIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uDQogKg0KICogRElTQ0xBSU1FUjogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBBVE1FTCAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUg0KICogSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRg0KICogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVCBBUkUNCiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEFUTUVMIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsDQogKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UDQogKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwNCiAqIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YNCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HDQogKiBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsDQogKiBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLg0KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KICovDQoNCi8qKg0KICogXGZpbGUNCiAqDQogKiBJbXBsZW1lbnRhdGlvbiBvZiBtZW1vcmllcyBjb25maWd1cmF0aW9uIG9uIGJvYXJkLg0KICoNCiAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoqICAgICAgICBIZWFkZXJzDQoqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQojaW5jbHVkZSAiY2hpcC5oIg0KDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiogICAgICAgIExvY2FsIGZ1bmN0aW9ucw0KKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KLyoqDQogKiBcYnJpZWYgQ2FsY3VsYXRlIHRoZSBzZHJhbSBjb250cm9sbGVyIGNvbmZpZyByZWdpc3RlciB2YWx1ZS4NCiAqIFxwYXJhbSBwTWVtb3J5ICBQb2ludGVyIHRvIHRoZSBzZHJhbSBzdHJ1Y3R1cmUuDQogKiBccmV0dXJuIENvbmZpZ3VyZSByZWdpc3RlciB2YWx1ZS4NCiAqLw0Kc3RhdGljIHVpbnQzMl90IFNEUkFNQ19jb21wdXRlX0NSX3ZhbHVlKCBTU2RyYW1jX01lbW9yeSogcE1lbW9yeSApDQp7DQogICAgdWludDMyX3QgZHc9MCA7DQoNCiAgICBkdyB8PSBwTWVtb3J5LT5jZmcuZHdDb2x1bW5CaXRzIDsNCiAgICBkdyB8PSBwTWVtb3J5LT5jZmcuZHdSb3dCaXRzIDsNCiAgICBkdyB8PSBwTWVtb3J5LT5jZmcuZHdCYW5rcyA7ICAvL05CLCBudW1iZXIgb2YgYmFua3MNCiAgICBkdyB8PSBwTWVtb3J5LT5jZmcuZHdDQVMgOyAgLy9DQVMsIENBUyBsYXRlbmN5DQogICAgZHcgfD0gcE1lbW9yeS0+Y2ZnLmR3RGF0YUJ1c1dpZHRoIDsgIC8vREJXLCBkYXRhIGJ1cyB3aWR0aA0KICAgIGR3IHw9IFNEUkFNQ19DUl9UV1IoIHBNZW1vcnktPmNmZy5kd1dyaXRlUmVjb3ZlcnlEZWxheSApIDsgIC8vVFdSLCBXcml0ZSBSZWNvdmVyeSBEZWxheQ0KICAgIGR3IHw9IFNEUkFNQ19DUl9UUkNfVFJGQyggcE1lbW9yeS0+Y2ZnLmR3Um93Q3ljbGVEZWxheV9Sb3dSZWZyZXNoQ3ljbGUgKSA7ICAvL1RSQ19UUkZDLFJvdyBDeWNsZSBEZWxheSBhbmQgUm93IFJlZnJlc2ggQ3ljbGUNCiAgICBkdyB8PSBTRFJBTUNfQ1JfVFJQKCBwTWVtb3J5LT5jZmcuZHdSb3dQcmVjaGFyZ2VEZWxheSApIDsgIC8vVFJQLCBSb3cgUHJlY2hhcmdlIERlbGF5DQogICAgZHcgfD0gU0RSQU1DX0NSX1RSQ0QoIHBNZW1vcnktPmNmZy5kd1Jvd0NvbHVtbkRlbGF5ICkgOyAgLy9UUkNELCBSb3cgdG8gQ29sdW1uIERlbGF5DQogICAgZHcgfD0gU0RSQU1DX0NSX1RSQVMoIHBNZW1vcnktPmNmZy5kd0FjdGl2ZVByZWNoYXJnZURlbGF5ICkgOyAgLy9UUkFTLCBBY3RpdmUgdG8gUHJlY2hhcmdlIERlbGF5DQogICAgZHcgfD0gU0RSQU1DX0NSX1RYU1IoIHBNZW1vcnktPmNmZy5kd0V4aXRTZWxmUmVmcmVzaEFjdGl2ZURlbGF5ICkgOyAgLy9UWFNSLCBFeGl0IFNlbGYgUmVmcmVzaCB0byBBY3RpdmUgRGVsYXkNCg0KICAgIHJldHVybiBkdyA7DQp9DQoNCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KKiAgICAgICAgRXhwb3J0ZWQgZnVuY3Rpb25zDQoqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQovKioNCiAqIFxicmllZiBDb25maWd1cmUgYW5kIGluaXRpYWxpemUgdGhlIFNEUkFNIGNvbnRyb2xsZXIuDQogKiBccGFyYW0gcE1lbW9yeSAgUG9pbnRlciB0byB0aGUgc2RyYW0gc3RydWN0dXJlLg0KICogXHBhcmFtIGR3Q2xvY2tGcmVxdWVuY3kgIFNEUkFNIGNsb2NrIGZyZXF1ZW5jeS4NCiAqLw0KZXh0ZXJuIHZvaWQgU0RSQU1DX0NvbmZpZ3VyZSggU1NkcmFtY19NZW1vcnkqIHBNZW1vcnksIHVpbnQzMl90IGR3Q2xvY2tGcmVxdWVuY3kgKQ0Kew0KICAgIHZvbGF0aWxlIHVpbnQzMl90IGR3IDsNCg0KICAgIC8qIFNEUkFNIGhhcmR3YXJlIGluaXQgKi8NCiAgICAvKiBFbmFibGUgcGVyaXBoZXJhbCBjbG9jayAqLw0KICAgIFBNQ19FbmFibGVQZXJpcGhlcmFsKCBJRF9TTUMgKSA7DQoNCiAgICAvKiBTRFJBTSBkZXZpY2UgY29uZmlndXJlICovDQogICAgLyogU3RlcCAxLiAqLw0KICAgIC8qIFByb2dyYW0gdGhlIGZlYXR1cmVzIG9mIFNEUkFNIGRldmljZSBpbnRvIHRoZSBDb25maWd1cmF0aW9uIFJlZ2lzdGVyLiovDQogICAgU0RSQU1DLT5TRFJBTUNfQ1IgPSBTRFJBTUNfY29tcHV0ZV9DUl92YWx1ZSggcE1lbW9yeSApIDsNCg0KICAgIC8qIFN0ZXAgMi4gKi8NCiAgICAvKiBGb3IgbG93LXBvd2VyIFNEUkFNLCB0ZW1wZXJhdHVyZS1jb21wZW5zYXRlZCBzZWxmIHJlZnJlc2ggKFRDU1IpLA0KICAgIGRyaXZlIHN0cmVuZ3RoIChEUykgYW5kIHBhcnRpYWwgYXJyYXkgc2VsZiByZWZyZXNoIChQQVNSKSBtdXN0IGJlIHNldA0KICAgIGluIHRoZSBMb3ctcG93ZXIgUmVnaXN0ZXIuKi8NCiAgICBTRFJBTUMtPlNEUkFNQ19MUFIgPSAwOw0KDQogICAgLyogU3RlcCAzLiAqLw0KICAgIC8qIFByb2dyYW0gdGhlIG1lbW9yeSBkZXZpY2UgdHlwZSBpbnRvIHRoZSBNZW1vcnkgRGV2aWNlIFJlZ2lzdGVyICovDQogICAgU0RSQU1DLT5TRFJBTUNfTURSID0gU0RSQU1DX01EUl9NRF9TRFJBTTsNCg0KICAgIC8qIFN0ZXAgNCAqLw0KICAgIC8qIEEgbWluaW11bSBwYXVzZSBvZiAyMDAgpsxzIGlzIHByb3ZpZGVkIHRvIHByZWNlZGUgYW55IHNpZ25hbCB0b2dnbGUuDQogICAgKDYgY29yZSBjeWNsZXMgcGVyIGl0ZXJhdGlvbikgKi8NCiAgICBmb3IgKCBkdyA9IDA7IGR3IDwgKChkd0Nsb2NrRnJlcXVlbmN5LzEwMDAwMDApKjIwMC82KSA7IGR3KysgKQ0KICAgIHsNCiAgICAgICAgOw0KICAgIH0NCg0KICAgIC8qIFN0ZXAgNS4gKi8NCiAgICAvKiBBIE5PUCBjb21tYW5kIGlzIGlzc3VlZCB0byB0aGUgU0RSLVNEUkFNLiBQcm9ncmFtIE5PUCBjb21tYW5kIGludG8NCiAgICBNb2RlIFJlZ2lzdGVyLCB0aGUgYXBwbGljYXRpb24gbXVzdCBzZXQgTW9kZSB0byAxIGluIHRoZSBNb2RlIFJlZ2lzdGVyLg0KICAgIFBlcmZvcm0gYSB3cml0ZSBhY2Nlc3MgdG8gYW55IFNEUi1TRFJBTSBhZGRyZXNzIHRvIGFja25vd2xlZGdlIHRoaXMgY29tbWFuZC4NCiAgICBOb3cgdGhlIGNsb2NrIHdoaWNoIGRyaXZlcyBTRFItU0RSQU0gZGV2aWNlIGlzIGVuYWJsZWQuKi8NCiAgICBTRFJBTUMtPlNEUkFNQ19NUiA9IFNEUkFNQ19NUl9NT0RFX05PUDsNCiAgICAqKHVpbnQxNl90ICopKEVCSV9TRFJBTUNfQUREUikgPSAwOw0KDQogICAgLyogU3RlcCA2LiAqLw0KICAgIC8qIEFuIGFsbCBiYW5rcyBwcmVjaGFyZ2UgY29tbWFuZCBpcyBpc3N1ZWQgdG8gdGhlIFNEUi1TRFJBTS4gUHJvZ3JhbSBhbGwNCiAgICBiYW5rcyBwcmVjaGFyZ2UgY29tbWFuZCBpbnRvIE1vZGUgUmVnaXN0ZXIsIHRoZSBhcHBsaWNhdGlvbiBtdXN0IHNldCBNb2RlIHRvDQogICAgMiBpbiB0aGUgTW9kZSBSZWdpc3RlciAuIFBlcmZvcm0gYSB3cml0ZSBhY2Nlc3MgdG8gYW55IFNEUlNEUkFNIGFkZHJlc3MgdG8NCiAgICBhY2tub3dsZWRnZSB0aGlzIGNvbW1hbmQuICovDQogICAgU0RSQU1DLT5TRFJBTUNfTVIgPSBTRFJBTUNfTVJfTU9ERV9BTExCQU5LU19QUkVDSEFSR0U7DQogICAgKih1aW50MTZfdCAqKShFQklfU0RSQU1DX0FERFIpID0gMHgwOw0KDQogICAgLyogYWRkIHNvbWUgZGVsYXlzIGFmdGVyIHByZWNoYXJnZSAqLw0KICAgIGZvciAoIGR3ID0gMDsgZHcgPCAoKGR3Q2xvY2tGcmVxdWVuY3kvMTAwMDAwMCkqMjAwLzYpIDsgZHcrKyApDQogICAgew0KICAgICAgICA7DQogICAgfQ0KDQogICAgLyogU3RlcCA3LiAqLw0KICAgIC8qIEVpZ2h0IGF1dG8tcmVmcmVzaCAoQ0JSKSBjeWNsZXMgYXJlIHByb3ZpZGVkLiBQcm9ncmFtIHRoZSBhdXRvIHJlZnJlc2gNCiAgICBjb21tYW5kIChDQlIpIGludG8gTW9kZSBSZWdpc3RlciwgdGhlIGFwcGxpY2F0aW9uIG11c3Qgc2V0IE1vZGUgdG8gNCBpbg0KICAgIHRoZSBNb2RlIFJlZ2lzdGVyLiBPbmNlIGluIHRoZSBpZGxlIHN0YXRlLCBlaWdodCBBVVRPIFJFRlJFU0ggY3ljbGVzIG11c3QNCiAgICBiZSBwZXJmb3JtZWQuICovDQogICAgU0RSQU1DLT5TRFJBTUNfTVIgPSBTRFJBTUNfTVJfTU9ERV9BVVRPX1JFRlJFU0g7DQogICAgKih1aW50MTZfdCAqKShFQklfU0RSQU1DX0FERFIgKyAwICkgPSAweDE7DQoNCiAgICBTRFJBTUMtPlNEUkFNQ19NUiA9IFNEUkFNQ19NUl9NT0RFX0FVVE9fUkVGUkVTSDsNCiAgICAqKHVpbnQxNl90ICopKEVCSV9TRFJBTUNfQUREUiArIDApID0gMHgyOw0KDQogICAgU0RSQU1DLT5TRFJBTUNfTVIgPSBTRFJBTUNfTVJfTU9ERV9BVVRPX1JFRlJFU0g7DQogICAgKih1aW50MTZfdCAqKShFQklfU0RSQU1DX0FERFIgKyAwICkgPSAweDM7DQoNCiAgICBTRFJBTUMtPlNEUkFNQ19NUiA9IFNEUkFNQ19NUl9NT0RFX0FVVE9fUkVGUkVTSDsNCiAgICAqKHVpbnQxNl90ICopKEVCSV9TRFJBTUNfQUREUiArIDApID0gMHg0Ow0KDQogICAgU0RSQU1DLT5TRFJBTUNfTVIgPSBTRFJBTUNfTVJfTU9ERV9BVVRPX1JFRlJFU0g7DQogICAgKih1aW50MTZfdCAqKShFQklfU0RSQU1DX0FERFIgKyAwICkgPSAweDU7DQoNCiAgICBTRFJBTUMtPlNEUkFNQ19NUiA9IFNEUkFNQ19NUl9NT0RFX0FVVE9fUkVGUkVTSDsNCiAgICAqKHVpbnQxNl90ICopKEVCSV9TRFJBTUNfQUREUiArIDApID0gMHg2Ow0KDQogICAgU0RSQU1DLT5TRFJBTUNfTVIgPSBTRFJBTUNfTVJfTU9ERV9BVVRPX1JFRlJFU0g7DQogICAgKih1aW50MTZfdCAqKShFQklfU0RSQU1DX0FERFIgKyAwICkgPSAweDc7DQoNCiAgICBTRFJBTUMtPlNEUkFNQ19NUiA9IFNEUkFNQ19NUl9NT0RFX0FVVE9fUkVGUkVTSDsNCiAgICAqKHVpbnQxNl90ICopKEVCSV9TRFJBTUNfQUREUiArIDApID0gMHg4Ow0KDQogICAgLyogU3RlcCA4LiAqLw0KICAgIC8qIEEgTW9kZSBSZWdpc3RlciBzZXQgKE1SUykgY3ljbGUgaXMgaXNzdWVkIHRvIHByb2dyYW0gdGhlIHBhcmFtZXRlcnMgb2YNCiAgICB0aGUgU0RSQU0gZGV2aWNlcywgaW4gcGFydGljdWxhciBDQVMgbGF0ZW5jeSBhbmQgYnVyc3QgbGVuZ3RoLiAqLw0KICAgIFNEUkFNQy0+U0RSQU1DX01SID0gU0RSQU1DX01SX01PREVfTE9BRF9NT0RFUkVHOw0KICAgICoodWludDE2X3QgKikoRUJJX1NEUkFNQ19BRERSICsgMHgyMikgPSAweGNhZmU7DQoNCiAgICAvKiBTdGVwIDkuICovDQogICAgLyogRm9yIGxvdy1wb3dlciBTRFItU0RSQU0gaW5pdGlhbGl6YXRpb24sIGFuIEV4dGVuZGVkIE1vZGUgUmVnaXN0ZXIgc2V0DQogICAgKEVNUlMpIGN5Y2xlIGlzIGlzc3VlZCB0byBwcm9ncmFtIHRoZSBTRFItU0RSQU0gcGFyYW1ldGVycyAoVENTUiwgUEFTUiwgRFMpLg0KICAgIFRoZSB3cml0ZSBhZGRyZXNzIG11c3QgYmUgY2hvc2VuIHNvIHRoYXQgQkFbMV0gaXMgc2V0IHRvIDEgYW5kIEJBWzBdIGlzIHNldA0KICAgIHRvIDAgKi8NCiAgICBTRFJBTUMtPlNEUkFNQ19NUiA9IFNEUkFNQ19NUl9NT0RFX0VYVF9MT0FEX01PREVSRUc7DQogICAgKigodWludDE2X3QgKikoRUJJX1NEUkFNQ19BRERSICsgKDEgPDwgcE1lbW9yeS0+Y2ZnLmR3QksxKSkpID0gMDsNCg0KICAgIC8qIFN0ZXAgMTAuICovDQogICAgLyogVGhlIGFwcGxpY2F0aW9uIG11c3QgZ28gaW50byBOb3JtYWwgTW9kZSwgc2V0dGluZyBNb2RlIHRvIDAgaW4gdGhlIE1vZGUNCiAgICBSZWdpc3RlciBhbmQgcGVyZm9ybSBhIHdyaXRlIGFjY2VzcyBhdCBhbnkgbG9jYXRpb24gaW4gdGhlIFNEUkFNIHRvDQogICAgYWNrbm93bGVkZ2UgdGhpcyBjb21tYW5kLiAqLw0KICAgIFNEUkFNQy0+U0RSQU1DX01SID0gU0RSQU1DX01SX01PREVfTk9STUFMOw0KICAgICoodWludDE2X3QgKikoRUJJX1NEUkFNQ19BRERSICkgPSAweDA7DQoNCiAgICAvKiBTdGVwIDExLiAqLw0KICAgIC8qIFdyaXRlIHRoZSByZWZyZXNoIHJhdGUgaW50byB0aGUgY291bnQgZmllbGQgaW4gdGhlIFNEUkFNQyBSZWZyZXNoDQogICAgIFRpbWVyIHJlZ2lzdGVyLiBTZXQgUmVmcmVzaCB0aW1lciAxNS42MjUgdXMqLw0KICAgIGR3PWR3Q2xvY2tGcmVxdWVuY3kvMTAwMHUgOw0KICAgIGR3Kj0xNTYyNXUgOw0KICAgIGR3Lz0xMDAwMDAwdSA7DQogICAgU0RSQU1DLT5TRFJBTUNfVFIgPSBTRFJBTUNfVFJfQ09VTlQoIGR3ICkgOw0KfQ0KDQo=