Performance degrade observed with OpenLDAP 2.6.7 library
venugopal chinnakotla <[email protected]> Thu, 12 Mar 2026 23:02:50 +0530
| Newsgroups | gmane.network.openldap.devel,gmane.network.openldap.technical |
|---|---|
| Message-ID | <CAJCMw6umQktZ9-TeiZBu9F21a-VczNfTHitKpdOzNrH8Wy8Erg@mail.gmail.com> |
--000000000000f8603e064cd72409 Content-Type: multipart/alternative; boundary="000000000000f8603d064cd72407" --000000000000f8603d064cd72407 Content-Type: text/plain; charset="UTF-8" Hi Team, We are working on migration of nsldap C sdk to OpenLDAP C sdk for our application client code. We are using OpenLDAP 2.6.7. As part of this migration, we are facing one issue related to performance degradation under load on Windows platform. In our application, we are using a single/shared connection handle to perform LDAP operation on LDAP user store servers. As part of Authentication, we are using ldap_search_ext_s call to get users and to get any user attributes from LDAP servers. We are using synchronous calls. With Mozilla NSLDAP, the same application is working well without any issues. As we are migrating to OpenLDAP, we did required changes and also we used ldap_dup() API to avoid "-4:Decoding error" issues under the load. Now, we are facing performance degradation issues under the load with OpenLDAP library Whenever we are trying to get a user attribute from the LDAP user store server where that user attribute is not available or value for user attribute is empty, we observed performance degradation with OpenLDAP library clearly around 25-30%. In case, search for user attributes with value, no degradation observed. This degradation is happening only when the user attribute is not available or the value is empty. Here are the snippet of runs output where performance degrade is showing: *With search of user attribute having value at LDAP server side:* Total Elapsed: 0:10:01 Minimum Response Time: 0:00:00.000.056 Maximum Response Time: 0:00:00.783.140 Average Response Time: 0:00:00.016.124 Total Requests: 659316 Throughput (Req/Sec): 1094.447 *With search of user attribute, not having value/does not exist at LDAP server side:* Total Elapsed: 0:10:01 Minimum Response Time: 0:00:00.000.059 Maximum Response Time: 0:00:00.218.502 Average Response Time: 0:00:00.032.788 Total Requests: 355065 Throughput (Req/Sec): 590.258 Example search calls we are using: 1. ldap_search_ext_x() for user lookup 2. ldap_search_ext_s() for user attributes for that specific user. (filter: uid=* and base: "cn=user,dc=comain,dc=com) - Where uid attribute has some value for this user at LDAP server side 3. ldap_search_ext_s() for user attributes for that specific user. (filter: Name=* and base: "cn=user,dc=comain,dc=com) - Where Name attribute is not present for that user at LDAP server side (This is causing performance degrade) With the same above steps, we did not see any performance issues with NSLDAP. If we remove step 3 from the above, no degradation is observed with the OpenLDAP library. Could you please look into this issue and provide a solution to overcome this performance degradation issue? We are completely blocked here as part of OpenLDAP migration. Note: To investigate this performance degradation with OpenLDAP, I wrote one LDAP sample code with the above 3 operations with multiple threads. I executed the sample with NSLDAP and OpenLDAP using multiple threads. In the sample runs, OpenLDAP is giving very poor performance when compared with NSLDAP. Please have a look at the sample also and provide your thoughts. Thank you in advance for your time and help --000000000000f8603d064cd72407 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div dir=3D"ltr"><div>Hi Team,</div><div><br></div><div>We= are working on migration of nsldap C sdk to OpenLDAP C sdk for our applica= tion client code.</div><div><div><div><br>We are using OpenLDAP 2.6.7.</div= ><div><br></div><div>As part of this migration, we are facing one issue rel= ated to performance degradation=C2=A0under load on Windows platform.</div><= /div><div><br></div><div>In our application, we are using a single/shared c= onnection handle to perform LDAP operation on LDAP user store servers. As p= art of Authentication, we are using ldap_search_ext_s call to get users and= to get any user attributes from LDAP servers. We are using synchronous cal= ls.</div><div>With Mozilla NSLDAP, the same application is working well wit= hout any issues. As we are migrating to OpenLDAP, we did required changes a= nd also we used ldap_dup() API to avoid "-4:Decoding error" issue= s under the load.</div><div><br></div><div>Now, we are facing performance d= egradation issues under the load with OpenLDAP library</div><div>Whenever w= e are trying to get a user attribute=C2=A0from the LDAP user store server w= here that user attribute is not available or value for user attribute is em= pty, we observed performance degradation with OpenLDAP library clearly arou= nd 25-30%. In case, search for user attributes with value, no degradation o= bserved. This degradation is happening only when the user attribute is not = available or the value is empty.<br><br>Here are the snippet of runs output= where performance degrade is showing:</div><div><b><br></b></div><div><b>W= ith search of user attribute having value at LDAP server side:</b><br><br><= /div><div>Total Elapsed: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0:10:01</div><d= iv><br></div><div>Minimum Response Time: =C2=A0 0:00:00.000.056<br>Maximum = Response Time: =C2=A0 0:00:00.783.140<br>Average Response Time: =C2=A0 0:00= :00.016.124<br><br>Total Requests: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0659316= <br>Throughput (Req/Sec): =C2=A0 =C2=A01094.447<br><br></div><div><b>With s= earch of user attribute, not having value/does not exist at LDAP server sid= e:</b></div><div><br></div><div>Total Elapsed: =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 0:10:01<br><br>Minimum Response Time: =C2=A0 0:00:00.000.059<br>Maxi= mum Response Time: =C2=A0 0:00:00.218.502<br>Average Response Time: =C2=A0 = 0:00:00.032.788<br><br>Total Requests: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A035= 5065<br>Throughput (Req/Sec): =C2=A0 =C2=A0590.258</div><div><br></div></di= v><div><br></div><div>Example search calls we are using:</div><div>1. ldap_= search_ext_x() for user lookup</div><div>2. ldap_search_ext_s() for user at= tributes=C2=A0for that specific user. (filter: uid=3D* and base: "cn= =3Duser,dc=3Dcomain,dc=3Dcom) - Where uid attribute has some value for this= user at LDAP server side</div><div>3. ldap_search_ext_s() for user attribu= tes=C2=A0for that specific user. (filter: Name=3D* and base: "cn=3Duse= r,dc=3Dcomain,dc=3Dcom) - Where Name attribute is not present for that user= at LDAP server side (This is causing performance degrade)</div><div><br></= div><div>With the same above steps, we did not see any performance issues w= ith NSLDAP. If we remove=C2=A0step=C2=A03 from the above, no degradation is= observed with the OpenLDAP library.</div><div><br>Could you please look in= to this issue and provide a solution to overcome this performance degradati= on issue? We are completely blocked here as part of OpenLDAP migration.<br>= <br>Note: To investigate this performance degradation with OpenLDAP, I wrot= e one LDAP sample code with the above 3 operations with multiple threads. I= executed the sample with NSLDAP and OpenLDAP using multiple threads. In th= e sample runs, OpenLDAP is giving very poor performance when compared with = NSLDAP. Please have a look at the sample also and provide your thoughts.</d= iv><div><br></div><div>Thank you in advance for your time and help<br><br><= /div><div><br></div><div><br></div><br></div></div> --000000000000f8603d064cd72407-- --000000000000f8603e064cd72409 Content-Type: application/octet-stream; name="LDAPBenchMark.cpp" Content-Disposition: attachment; filename="LDAPBenchMark.cpp" Content-Transfer-Encoding: base64 Content-ID: <f_mmnqv76d0> X-Attachment-Id: f_mmnqv76d0 I2luY2x1ZGUgPGxkYXAuaD4NCiNpbmNsdWRlIDxpb3N0cmVhbT4NCiNpbmNsdWRlIDxjaHJvbm8+ DQojaW5jbHVkZSA8dmVjdG9yPg0KI2luY2x1ZGUgPHN0cmluZz4NCiNpbmNsdWRlIDxjc3RyaW5n Pg0KI2luY2x1ZGUgPGlvbWFuaXA+DQojaW5jbHVkZSA8YWxnb3JpdGhtPg0KI2luY2x1ZGUgPHRo cmVhZD4NCiNpbmNsdWRlIDxtdXRleD4NCiNpbmNsdWRlIDxhdG9taWM+DQoNCnVzaW5nIG5hbWVz cGFjZSBzdGQ7DQp1c2luZyBuYW1lc3BhY2Ugc3RkOjpjaHJvbm87DQoNCi8vIENvbmZpZ3VyYXRp b24gc3RydWN0dXJlDQpzdHJ1Y3QgTERBUENvbmZpZyB7DQogICAgc3RyaW5nIGxkYXBIb3N0Ow0K ICAgIGludCBsZGFwUG9ydDsNCiAgICBzdHJpbmcgYmluZEROOw0KICAgIHN0cmluZyBiaW5kUGFz c3dvcmQ7DQogICAgc3RyaW5nIGJhc2VETjsNCiAgICBzdHJpbmcgc2VhcmNoVXNlcjsNCiAgICBp bnQgdGltZW91dDsNCn07DQoNCi8vIFN0YXRpc3RpY3Mgc3RydWN0dXJlIGZvciB0cmFja2luZyBv cGVyYXRpb24gdGltaW5ncyAodGhyZWFkLXNhZmUpDQpzdHJ1Y3QgT3BlcmF0aW9uU3RhdHMgew0K ICAgIHZlY3Rvcjxkb3VibGU+IHRpbWluZ3M7DQogICAgc3RyaW5nIG9wZXJhdGlvbk5hbWU7DQog ICAgbXV0ZXggbXR4OyAgLy8gTXV0ZXggZm9yIHRocmVhZC1zYWZlIGFjY2Vzcw0KDQogICAgdm9p ZCBhZGRUaW1pbmcoZG91YmxlIG1zKSB7DQogICAgICAgIGxvY2tfZ3VhcmQ8bXV0ZXg+IGxvY2so bXR4KTsNCiAgICAgICAgdGltaW5ncy5wdXNoX2JhY2sobXMpOw0KICAgIH0NCg0KICAgIHZvaWQg cHJpbnRTdW1tYXJ5KCkgew0KICAgICAgICBsb2NrX2d1YXJkPG11dGV4PiBsb2NrKG10eCk7DQoN CiAgICAgICAgaWYgKHRpbWluZ3MuZW1wdHkoKSkgew0KICAgICAgICAgICAgY291dCA8PCAiXG4i IDw8IG9wZXJhdGlvbk5hbWUgPDwgIjogTm8gb3BlcmF0aW9ucyBjb21wbGV0ZWQiIDw8IGVuZGw7 DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCg0KICAgICAgICBzb3J0KHRpbWluZ3Mu YmVnaW4oKSwgdGltaW5ncy5lbmQoKSk7DQoNCiAgICAgICAgZG91YmxlIHN1bSA9IDA7DQogICAg ICAgIGZvciAoZG91YmxlIHQgOiB0aW1pbmdzKSBzdW0gKz0gdDsNCiAgICAgICAgZG91YmxlIGF2 ZyA9IHN1bSAvIHRpbWluZ3Muc2l6ZSgpOw0KDQogICAgICAgIGRvdWJsZSBtaW4gPSB0aW1pbmdz LmZyb250KCk7DQogICAgICAgIGRvdWJsZSBtYXggPSB0aW1pbmdzLmJhY2soKTsNCiAgICAgICAg ZG91YmxlIG1lZGlhbiA9IHRpbWluZ3NbdGltaW5ncy5zaXplKCkgLyAyXTsNCg0KICAgICAgICAv LyBDYWxjdWxhdGUgcGVyY2VudGlsZXMNCiAgICAgICAgZG91YmxlIHA5NSA9IHRpbWluZ3NbKGlu dCkodGltaW5ncy5zaXplKCkgKiAwLjk1KV07DQogICAgICAgIGRvdWJsZSBwOTkgPSB0aW1pbmdz WyhpbnQpKHRpbWluZ3Muc2l6ZSgpICogMC45OSldOw0KDQogICAgICAgIGNvdXQgPDwgIlxuPT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIgPDwgZW5kbDsNCiAgICAgICAg Y291dCA8PCBvcGVyYXRpb25OYW1lIDw8ICIgU3RhdGlzdGljczoiIDw8IGVuZGw7DQogICAgICAg IGNvdXQgPDwgIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iIDw8IGVu ZGw7DQogICAgICAgIGNvdXQgPDwgIlRvdGFsIE9wZXJhdGlvbnM6ICIgPDwgdGltaW5ncy5zaXpl KCkgPDwgZW5kbDsNCiAgICAgICAgY291dCA8PCAiQXZlcmFnZSBUaW1lOiAgICAgIiA8PCBmaXhl ZCA8PCBzZXRwcmVjaXNpb24oMykgPDwgYXZnIDw8ICIgbXMiIDw8IGVuZGw7DQogICAgICAgIGNv dXQgPDwgIk1lZGlhbiBUaW1lOiAgICAgICIgPDwgZml4ZWQgPDwgc2V0cHJlY2lzaW9uKDMpIDw8 IG1lZGlhbiA8PCAiIG1zIiA8PCBlbmRsOw0KICAgICAgICBjb3V0IDw8ICJNaW4gVGltZTogICAg ICAgICAiIDw8IGZpeGVkIDw8IHNldHByZWNpc2lvbigzKSA8PCBtaW4gPDwgIiBtcyIgPDwgZW5k bDsNCiAgICAgICAgY291dCA8PCAiTWF4IFRpbWU6ICAgICAgICAgIiA8PCBmaXhlZCA8PCBzZXRw cmVjaXNpb24oMykgPDwgbWF4IDw8ICIgbXMiIDw8IGVuZGw7DQogICAgICAgIGNvdXQgPDwgIjk1 dGggUGVyY2VudGlsZTogICIgPDwgZml4ZWQgPDwgc2V0cHJlY2lzaW9uKDMpIDw8IHA5NSA8PCAi IG1zIiA8PCBlbmRsOw0KICAgICAgICBjb3V0IDw8ICI5OXRoIFBlcmNlbnRpbGU6ICAiIDw8IGZp eGVkIDw8IHNldHByZWNpc2lvbigzKSA8PCBwOTkgPDwgIiBtcyIgPDwgZW5kbDsNCiAgICAgICAg Y291dCA8PCAiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIgPDwgZW5k bDsNCiAgICB9DQp9Ow0KDQpjbGFzcyBTaGFyZWRMREFQQmVuY2htYXJrIHsNCnByaXZhdGU6DQog ICAgTERBUCogbGQ7ICAvLyBTaGFyZWQgTERBUCBjb25uZWN0aW9uIGhhbmRsZQ0KICAgIExEQVBD b25maWcgY29uZmlnOw0KICAgIG11dGV4IGxkYXBNdXRleDsgIC8vIE11dGV4IHRvIHByb3RlY3Qg TERBUCBvcGVyYXRpb25zIChpZiBuZWVkZWQpDQoNCnB1YmxpYzoNCiAgICBTaGFyZWRMREFQQmVu Y2htYXJrKGNvbnN0IExEQVBDb25maWcmIGNmZykgOiBsZChudWxscHRyKSwgY29uZmlnKGNmZykg e30NCg0KICAgIH5TaGFyZWRMREFQQmVuY2htYXJrKCkgew0KICAgICAgICBpZiAobGQpIHsNCiAg ICAgICAgICAgIGxkYXBfdW5iaW5kKGxkKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIGJvb2wg aW5pdGlhbGl6ZSgpIHsNCiAgICAgICAgaW50IHJjOw0KDQogICAgICAgIGNvdXQgPDwgIkluaXRp YWxpemluZyBzaGFyZWQgTERBUCBjb25uZWN0aW9uIGluIG1haW4gdGhyZWFkLi4uIiA8PCBlbmRs Ow0KDQogICAgICAgIC8vIEluaXRpYWxpemUgTERBUCBjb25uZWN0aW9uIChNb3ppbGxhIE5TTERB UCBzdHlsZSkNCiAgICAgICAgbGQgPSBsZGFwX2luaXQoKGNoYXIqKWNvbmZpZy5sZGFwSG9zdC5j X3N0cigpLCBjb25maWcubGRhcFBvcnQpOw0KICAgICAgICBpZiAobGQgPT0gbnVsbHB0cikgew0K ICAgICAgICAgICAgY2VyciA8PCAibGRhcF9pbml0IGZhaWxlZCIgPDwgZW5kbDsNCiAgICAgICAg ICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFNldCBMREFQIHZlcnNp b24gdG8gMw0KICAgICAgICBpbnQgdmVyc2lvbiA9IExEQVBfVkVSU0lPTjM7DQogICAgICAgIHJj ID0gbGRhcF9zZXRfb3B0aW9uKGxkLCBMREFQX09QVF9QUk9UT0NPTF9WRVJTSU9OLCAmdmVyc2lv bik7DQogICAgICAgIGlmIChyYyAhPSBMREFQX1NVQ0NFU1MpIHsNCiAgICAgICAgICAgIGNlcnIg PDwgImxkYXBfc2V0X29wdGlvbiAoUFJPVE9DT0xfVkVSU0lPTikgZmFpbGVkOiAiIDw8IGxkYXBf ZXJyMnN0cmluZyhyYykgPDwgZW5kbDsNCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAg ICAgfQ0KDQogICAgICAgIC8vIFNldCB0aW1lb3V0IChpbiBzZWNvbmRzKQ0KICAgICAgICBpbnQg dGltZW91dCA9IGNvbmZpZy50aW1lb3V0Ow0KICAgICAgICBsZGFwX3NldF9vcHRpb24obGQsIExE QVBfT1BUX1RJTUVMSU1JVCwgJnRpbWVvdXQpOw0KDQogICAgICAgIC8vIEJpbmQgdG8gTERBUCBz ZXJ2ZXIgKHNpbXBsZSBiaW5kKQ0KICAgICAgICByYyA9IGxkYXBfc2ltcGxlX2JpbmRfcyhsZCwN CiAgICAgICAgICAgIChjaGFyKiljb25maWcuYmluZEROLmNfc3RyKCksDQogICAgICAgICAgICAo Y2hhciopY29uZmlnLmJpbmRQYXNzd29yZC5jX3N0cigpKTsNCiAgICAgICAgaWYgKHJjICE9IExE QVBfU1VDQ0VTUykgew0KICAgICAgICAgICAgY2VyciA8PCAibGRhcF9zaW1wbGVfYmluZF9zIGZh aWxlZDogIiA8PCBsZGFwX2VycjJzdHJpbmcocmMpIDw8IGVuZGw7DQogICAgICAgICAgICByZXR1 cm4gZmFsc2U7DQogICAgICAgIH0NCg0KICAgICAgICBjb3V0IDw8ICJTdWNjZXNzZnVsbHkgY29u bmVjdGVkIGFuZCBib3VuZCB0byBMREFQIHNlcnZlciIgPDwgZW5kbDsNCiAgICAgICAgY291dCA8 PCAiTERBUCBjb25uZWN0aW9uIGhhbmRsZSB3aWxsIGJlIHNoYXJlZCBhY3Jvc3MgYWxsIHRocmVh ZHMiIDw8IGVuZGw7DQogICAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCg0KICAgIC8vIFRhc2sg MTogU2ltcGxlIHVzZXIgc2VhcmNoDQogICAgZG91YmxlIHRhc2sxX3VzZXJTZWFyY2goaW50IHRo cmVhZElkKSB7DQogICAgICAgIGF1dG8gc3RhcnQgPSBoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5v dygpOw0KDQogICAgICAgIHN0cmluZyBmaWx0ZXIgPSAiKHVpZD0iICsgY29uZmlnLnNlYXJjaFVz ZXIgKyAiKSI7DQogICAgICAgIGNoYXIqIGF0dHJzW10gPSB7IChjaGFyKikidWlkIiwgbnVsbHB0 ciB9Ow0KDQogICAgICAgIExEQVBNZXNzYWdlKiByZXN1bHQgPSBudWxscHRyOw0KDQogICAgICAg IC8vIE5vdGU6IExEQVAgb3BlcmF0aW9ucyBvbiBzaGFyZWQgaGFuZGxlDQogICAgICAgIC8vIFNv bWUgTERBUCBpbXBsZW1lbnRhdGlvbnMgYXJlIHRocmVhZC1zYWZlLCBzb21lIHJlcXVpcmUgZXh0 ZXJuYWwgc3luY2hyb25pemF0aW9uDQogICAgICAgIC8vIFVuY29tbWVudCB0aGUgbXV0ZXggbG9j ayBpZiB5b3UgZXhwZXJpZW5jZSBpc3N1ZXMNCiAgICAgICAgLy8gbG9ja19ndWFyZDxtdXRleD4g bG9jayhsZGFwTXV0ZXgpOw0KDQogICAgICAgIGludCByYyA9IGxkYXBfc2VhcmNoX2V4dF9zKGxk LA0KICAgICAgICAgICAgKGNoYXIqKWNvbmZpZy5iYXNlRE4uY19zdHIoKSwNCiAgICAgICAgICAg IExEQVBfU0NPUEVfU1VCVFJFRSwNCiAgICAgICAgICAgIChjaGFyKilmaWx0ZXIuY19zdHIoKSwN CiAgICAgICAgICAgIGF0dHJzLA0KICAgICAgICAgICAgMCwNCiAgICAgICAgICAgIG51bGxwdHIs DQogICAgICAgICAgICBudWxscHRyLA0KICAgICAgICAgICAgbnVsbHB0ciwNCiAgICAgICAgICAg IDAsDQogICAgICAgICAgICAmcmVzdWx0KTsNCg0KICAgICAgICBhdXRvIGVuZCA9IGhpZ2hfcmVz b2x1dGlvbl9jbG9jazo6bm93KCk7DQoNCiAgICAgICAgaWYgKHJjICE9IExEQVBfU1VDQ0VTUykg ew0KICAgICAgICAgICAgcmV0dXJuIC0xLjA7DQogICAgICAgIH0NCg0KICAgICAgICBpZiAocmVz dWx0KSB7DQogICAgICAgICAgICBsZGFwX21zZ2ZyZWUocmVzdWx0KTsNCiAgICAgICAgfQ0KDQog ICAgICAgIGR1cmF0aW9uPGRvdWJsZSwgbWlsbGk+IGVsYXBzZWQgPSBlbmQgLSBzdGFydDsNCiAg ICAgICAgcmV0dXJuIGVsYXBzZWQuY291bnQoKTsNCiAgICB9DQoNCiAgICAvLyBUYXNrIDI6IEZl dGNoICJ1aWQiIGF0dHJpYnV0ZQ0KICAgIGRvdWJsZSB0YXNrMl9mZXRjaFVpZEF0dHJpYnV0ZShp bnQgdGhyZWFkSWQpIHsNCiAgICAgICAgYXV0byBzdGFydCA9IGhpZ2hfcmVzb2x1dGlvbl9jbG9j azo6bm93KCk7DQoNCiAgICAgICAgc3RyaW5nIGZpbHRlciA9ICJ1aWQ9KiI7DQogICAgICAgIGNo YXIqIGF0dHJzW10gPSB7IChjaGFyKikidWlkIiwgbnVsbHB0ciB9Ow0KDQogICAgICAgIExEQVBN ZXNzYWdlKiByZXN1bHQgPSBudWxscHRyOw0KDQogICAgICAgIC8vIFVuY29tbWVudCBpZiBzeW5j aHJvbml6YXRpb24gaXMgbmVlZGVkDQogICAgICAgIC8vIGxvY2tfZ3VhcmQ8bXV0ZXg+IGxvY2so bGRhcE11dGV4KTsNCg0KICAgICAgICBpbnQgcmMgPSBsZGFwX3NlYXJjaF9leHRfcyhsZCwNCiAg ICAgICAgICAgIChjaGFyKikiY249QUFBQUFBLG91PU9yZ1VuaXQwLG89c2VjdXJpdHkuY29tIiwN CiAgICAgICAgICAgIExEQVBfU0NPUEVfU1VCVFJFRSwNCiAgICAgICAgICAgIChjaGFyKilmaWx0 ZXIuY19zdHIoKSwNCiAgICAgICAgICAgIGF0dHJzLA0KICAgICAgICAgICAgMCwNCiAgICAgICAg ICAgIG51bGxwdHIsDQogICAgICAgICAgICBudWxscHRyLA0KICAgICAgICAgICAgbnVsbHB0ciwN CiAgICAgICAgICAgIDAsDQogICAgICAgICAgICAmcmVzdWx0KTsNCg0KICAgICAgICBpZiAocmMg IT0gTERBUF9TVUNDRVNTKSB7DQogICAgICAgICAgICByZXR1cm4gLTEuMDsNCiAgICAgICAgfQ0K DQogICAgICAgIC8vIENvdW50IGVudHJpZXMNCiAgICAgICAgaW50IGNvdW50ID0gbGRhcF9jb3Vu dF9lbnRyaWVzKGxkLCByZXN1bHQpOw0KDQogICAgICAgIGlmIChjb3VudCA+IDApIHsNCiAgICAg ICAgICAgIC8vIEdldCBmaXJzdCBlbnRyeQ0KICAgICAgICAgICAgTERBUE1lc3NhZ2UqIGVudHJ5 ID0gbGRhcF9maXJzdF9lbnRyeShsZCwgcmVzdWx0KTsNCg0KICAgICAgICAgICAgaWYgKGVudHJ5 KSB7DQogICAgICAgICAgICAgICAgLy8gR2V0IGZpcnN0IGF0dHJpYnV0ZQ0KICAgICAgICAgICAg ICAgIEJlckVsZW1lbnQqIGJlciA9IG51bGxwdHI7DQogICAgICAgICAgICAgICAgY2hhciogYXR0 ciA9IGxkYXBfZmlyc3RfYXR0cmlidXRlKGxkLCBlbnRyeSwgJmJlcik7DQoNCiAgICAgICAgICAg ICAgICBpZiAoYXR0cikgew0KICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdmFsdWVzDQogICAg ICAgICAgICAgICAgICAgIGNoYXIqKiB2YWxzID0gbGRhcF9nZXRfdmFsdWVzKGxkLCBlbnRyeSwg YXR0cik7DQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHMpIHsNCiAgICAgICAgICAgICAg ICAgICAgICAgIGxkYXBfdmFsdWVfZnJlZSh2YWxzKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0K DQogICAgICAgICAgICAgICAgICAgIGxkYXBfbWVtZnJlZShhdHRyKTsNCiAgICAgICAgICAgICAg ICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoYmVyKSB7DQogICAgICAgICAgICAgICAgICAgIGJl cl9mcmVlKGJlciwgMCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAg ICB9DQoNCiAgICAgICAgaWYgKHJlc3VsdCkgew0KICAgICAgICAgICAgbGRhcF9tc2dmcmVlKHJl c3VsdCk7DQogICAgICAgIH0NCg0KICAgICAgICBhdXRvIGVuZCA9IGhpZ2hfcmVzb2x1dGlvbl9j bG9jazo6bm93KCk7DQogICAgICAgIGR1cmF0aW9uPGRvdWJsZSwgbWlsbGk+IGVsYXBzZWQgPSBl bmQgLSBzdGFydDsNCiAgICAgICAgcmV0dXJuIGVsYXBzZWQuY291bnQoKTsNCiAgICB9DQoNCiAg ICAvLyBUYXNrIDM6IEZldGNoICJOYW1lIiBhdHRyaWJ1dGUgKGNuIG9yIGRpc3BsYXlOYW1lKQ0K ICAgIGRvdWJsZSB0YXNrM19mZXRjaE5hbWVBdHRyaWJ1dGUoaW50IHRocmVhZElkKSB7DQogICAg ICAgIGF1dG8gc3RhcnQgPSBoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOw0KDQogICAgICAg IHN0cmluZyBmaWx0ZXIgPSAiTmFtZT0qIjsNCiAgICAgICAgY2hhciogYXR0cnNbXSA9IHsgKGNo YXIqKSJOYW1lIiwgbnVsbHB0ciB9Ow0KDQogICAgICAgIExEQVBNZXNzYWdlKiByZXN1bHQgPSBu dWxscHRyOw0KDQogICAgICAgIC8vIFVuY29tbWVudCBpZiBzeW5jaHJvbml6YXRpb24gaXMgbmVl ZGVkDQogICAgICAgIC8vIGxvY2tfZ3VhcmQ8bXV0ZXg+IGxvY2sobGRhcE11dGV4KTsNCg0KICAg ICAgICBpbnQgcmMgPSBsZGFwX3NlYXJjaF9leHRfcyhsZCwNCiAgICAgICAgICAgIChjaGFyKiki Y249QUFBQUFBLG91PU9yZ1VuaXQwLG89c2VjdXJpdHkuY29tIiwNCiAgICAgICAgICAgIExEQVBf U0NPUEVfU1VCVFJFRSwNCiAgICAgICAgICAgIChjaGFyKilmaWx0ZXIuY19zdHIoKSwNCiAgICAg ICAgICAgIGF0dHJzLA0KICAgICAgICAgICAgMCwNCiAgICAgICAgICAgIG51bGxwdHIsDQogICAg ICAgICAgICBudWxscHRyLA0KICAgICAgICAgICAgbnVsbHB0ciwNCiAgICAgICAgICAgIDAsDQog ICAgICAgICAgICAmcmVzdWx0KTsNCg0KICAgICAgICBpZiAocmMgIT0gTERBUF9TVUNDRVNTKSB7 DQogICAgICAgICAgICByZXR1cm4gLTEuMDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENvdW50 IGVudHJpZXMNCiAgICAgICAgaW50IGNvdW50ID0gbGRhcF9jb3VudF9lbnRyaWVzKGxkLCByZXN1 bHQpOw0KDQogICAgICAgIGlmIChjb3VudCA+IDApIHsNCiAgICAgICAgICAgIC8vIEdldCBmaXJz dCBlbnRyeQ0KICAgICAgICAgICAgTERBUE1lc3NhZ2UqIGVudHJ5ID0gbGRhcF9maXJzdF9lbnRy eShsZCwgcmVzdWx0KTsNCg0KICAgICAgICAgICAgaWYgKGVudHJ5KSB7DQogICAgICAgICAgICAg ICAgLy8gR2V0IGZpcnN0IGF0dHJpYnV0ZQ0KICAgICAgICAgICAgICAgIEJlckVsZW1lbnQqIGJl ciA9IG51bGxwdHI7DQogICAgICAgICAgICAgICAgY2hhciogYXR0ciA9IGxkYXBfZmlyc3RfYXR0 cmlidXRlKGxkLCBlbnRyeSwgJmJlcik7DQoNCiAgICAgICAgICAgICAgICB3aGlsZSAoYXR0cikg ew0KICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdmFsdWVzIGZvciB0aGlzIGF0dHJpYnV0ZQ0K ICAgICAgICAgICAgICAgICAgICBjaGFyKiogdmFscyA9IGxkYXBfZ2V0X3ZhbHVlcyhsZCwgZW50 cnksIGF0dHIpOw0KDQogICAgICAgICAgICAgICAgICAgIGlmICh2YWxzKSB7DQogICAgICAgICAg ICAgICAgICAgICAgICBsZGFwX3ZhbHVlX2ZyZWUodmFscyk7DQogICAgICAgICAgICAgICAgICAg IH0NCg0KICAgICAgICAgICAgICAgICAgICBsZGFwX21lbWZyZWUoYXR0cik7DQogICAgICAgICAg ICAgICAgICAgIGF0dHIgPSBsZGFwX25leHRfYXR0cmlidXRlKGxkLCBlbnRyeSwgYmVyKTsNCiAg ICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoYmVyKSB7DQogICAgICAgICAg ICAgICAgICAgIGJlcl9mcmVlKGJlciwgMCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAg ICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKHJlc3VsdCkgew0KICAgICAgICAgICAgbGRh cF9tc2dmcmVlKHJlc3VsdCk7DQogICAgICAgIH0NCg0KICAgICAgICBhdXRvIGVuZCA9IGhpZ2hf cmVzb2x1dGlvbl9jbG9jazo6bm93KCk7DQogICAgICAgIGR1cmF0aW9uPGRvdWJsZSwgbWlsbGk+ IGVsYXBzZWQgPSBlbmQgLSBzdGFydDsNCiAgICAgICAgcmV0dXJuIGVsYXBzZWQuY291bnQoKTsN CiAgICB9DQoNCiAgICB2b2lkIHJ1bkJlbmNobWFya1RocmVhZChpbnQgdGhyZWFkSWQsDQogICAg ICAgIGludCBkdXJhdGlvbk1pbnV0ZXMsDQogICAgICAgIE9wZXJhdGlvblN0YXRzJiBzdGF0czEs DQogICAgICAgIE9wZXJhdGlvblN0YXRzJiBzdGF0czIsDQogICAgICAgIE9wZXJhdGlvblN0YXRz JiBzdGF0czMsDQogICAgICAgIGF0b21pYzxpbnQ+JiB0b3RhbEl0ZXJhdGlvbnMpIHsNCg0KICAg ICAgICBhdXRvIHN0YXJ0VGltZSA9IGhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7DQogICAg ICAgIGF1dG8gZW5kVGltZSA9IHN0YXJ0VGltZSArIG1pbnV0ZXMoZHVyYXRpb25NaW51dGVzKTsN Cg0KICAgICAgICBjb3V0IDw8ICJbVGhyZWFkICIgPDwgdGhyZWFkSWQgPDwgIl0gU3RhcnRpbmcg YmVuY2htYXJrIHVzaW5nIHNoYXJlZCBMREFQIGNvbm5lY3Rpb24iIDw8IGVuZGw7DQoNCiAgICAg ICAgaW50IGxvY2FsSXRlcmF0aW9ucyA9IDA7DQoNCiAgICAgICAgd2hpbGUgKGhpZ2hfcmVzb2x1 dGlvbl9jbG9jazo6bm93KCkgPCBlbmRUaW1lKSB7DQogICAgICAgICAgICBsb2NhbEl0ZXJhdGlv bnMrKzsNCg0KICAgICAgICAgICAgLy8gVGFzayAxDQogICAgICAgICAgICBkb3VibGUgdGltZTEg PSB0YXNrMV91c2VyU2VhcmNoKHRocmVhZElkKTsNCiAgICAgICAgICAgIGlmICh0aW1lMSA+PSAw KSB7DQogICAgICAgICAgICAgICAgc3RhdHMxLmFkZFRpbWluZyh0aW1lMSk7DQogICAgICAgICAg ICB9DQoNCiAgICAgICAgICAgIC8vIFRhc2sgMg0KICAgICAgICAgICAgZG91YmxlIHRpbWUyID0g dGFzazJfZmV0Y2hVaWRBdHRyaWJ1dGUodGhyZWFkSWQpOw0KICAgICAgICAgICAgaWYgKHRpbWUy ID49IDApIHsNCiAgICAgICAgICAgICAgICBzdGF0czIuYWRkVGltaW5nKHRpbWUyKTsNCiAgICAg ICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gVGFzayAzDQogICAgICAgICAgICBkb3VibGUgdGlt ZTMgPSB0YXNrM19mZXRjaE5hbWVBdHRyaWJ1dGUodGhyZWFkSWQpOw0KICAgICAgICAgICAgaWYg KHRpbWUzID49IDApIHsNCiAgICAgICAgICAgICAgICBzdGF0czMuYWRkVGltaW5nKHRpbWUzKTsN CiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHRvdGFsSXRlcmF0aW9ucyArPSBs b2NhbEl0ZXJhdGlvbnM7DQogICAgICAgIGNvdXQgPDwgIltUaHJlYWQgIiA8PCB0aHJlYWRJZCA8 PCAiXSBDb21wbGV0ZWQgIiA8PCBsb2NhbEl0ZXJhdGlvbnMgPDwgIiBpdGVyYXRpb25zIiA8PCBl bmRsOw0KICAgIH0NCn07DQoNCi8vIFRocmVhZCB3b3JrZXIgZnVuY3Rpb24NCnZvaWQgdGhyZWFk V29ya2VyKGludCB0aHJlYWRJZCwNCiAgICBTaGFyZWRMREFQQmVuY2htYXJrKiBiZW5jaG1hcmss DQogICAgaW50IGR1cmF0aW9uTWludXRlcywNCiAgICBPcGVyYXRpb25TdGF0cyYgc3RhdHMxLA0K ICAgIE9wZXJhdGlvblN0YXRzJiBzdGF0czIsDQogICAgT3BlcmF0aW9uU3RhdHMmIHN0YXRzMywN CiAgICBhdG9taWM8aW50PiYgdG90YWxJdGVyYXRpb25zKSB7DQoNCiAgICBiZW5jaG1hcmstPnJ1 bkJlbmNobWFya1RocmVhZCh0aHJlYWRJZCwgZHVyYXRpb25NaW51dGVzLCBzdGF0czEsIHN0YXRz Miwgc3RhdHMzLCB0b3RhbEl0ZXJhdGlvbnMpOw0KfQ0KDQppbnQgbWFpbihpbnQgYXJnYywgY2hh ciogYXJndltdKSB7DQogICAgLy8gQ29uZmlndXJhdGlvbiAtIE1vZGlmeSB0aGVzZSB2YWx1ZXMg Zm9yIHlvdXIgTERBUCBzZXJ2ZXINCiAgICBMREFQQ29uZmlnIGNvbmZpZzsNCiAgICBjb25maWcu bGRhcEhvc3QgPSAiaWRwdXN0b3JlIjsgIC8vIENoYW5nZSB0byB5b3VyIExEQVAgc2VydmVyIGhv c3RuYW1lL0lQDQogICAgY29uZmlnLmxkYXBQb3J0ID0gMjIyMjI7ICAvLyBTdGFuZGFyZCBMREFQ IHBvcnQgKDYzNiBmb3IgTERBUFMpDQogICAgY29uZmlnLmJpbmRETiA9ICJjbj1hZG1pbixvPXNl Y3VyaXR5LmNvbSI7ICAvLyBDaGFuZ2UgdG8geW91ciBiaW5kIERODQogICAgY29uZmlnLmJpbmRQ YXNzd29yZCA9ICJmaXJld2FsbCI7ICAvLyBDaGFuZ2UgdG8geW91ciBwYXNzd29yZA0KICAgIGNv bmZpZy5iYXNlRE4gPSAibz1zZWN1cml0eS5jb20iOyAgLy8gQ2hhbmdlIHRvIHlvdXIgYmFzZSBE Tg0KICAgIGNvbmZpZy5zZWFyY2hVc2VyID0gIkFBQUFBQSI7ICAvLyBVc2VyIHRvIHNlYXJjaCBm b3INCiAgICBjb25maWcudGltZW91dCA9IDEwOyAgLy8gc2Vjb25kcw0KDQogICAgaW50IG51bVRo cmVhZHMgPSA1Ow0KICAgIGludCBkdXJhdGlvbk1pbnV0ZXMgPSAxMDsNCg0KICAgIC8vIEFsbG93 IGNvbW1hbmQtbGluZSBvdmVycmlkZXMNCi8qICAgIGlmIChhcmdjID4gMSkgY29uZmlnLmxkYXBI b3N0ID0gYXJndlsxXTsNCiAgICBpZiAoYXJnYyA+IDIpIGNvbmZpZy5sZGFwUG9ydCA9IGF0b2ko YXJndlsyXSk7DQogICAgaWYgKGFyZ2MgPiAzKSBjb25maWcuYmluZEROID0gYXJndlszXTsNCiAg ICBpZiAoYXJnYyA+IDQpIGNvbmZpZy5iaW5kUGFzc3dvcmQgPSBhcmd2WzRdOw0KICAgIGlmIChh cmdjID4gNSkgY29uZmlnLmJhc2VETiA9IGFyZ3ZbNV07DQogICAgaWYgKGFyZ2MgPiA2KSBjb25m aWcuc2VhcmNoVXNlciA9IGFyZ3ZbNl07Ki8NCg0KICAgIGlmIChhcmdjID4gMSkgbnVtVGhyZWFk cyA9IGF0b2koYXJndlsxXSk7DQogICAgaWYgKGFyZ2MgPiAyKSBkdXJhdGlvbk1pbnV0ZXMgPSBh dG9pKGFyZ3ZbMl0pOw0KDQogICAgY291dCA8PCAiPT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PSIgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICJMREFQIFNoYXJlZCBDb25uZWN0 aW9uIFBlcmZvcm1hbmNlIEJlbmNobWFyayIgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICI9PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IiA8PCBlbmRsOw0KICAgIGNvdXQgPDwg IkxEQVAgSG9zdDogICAgIiA8PCBjb25maWcubGRhcEhvc3QgPDwgIjoiIDw8IGNvbmZpZy5sZGFw UG9ydCA8PCBlbmRsOw0KICAgIGNvdXQgPDwgIkJhc2UgRE46ICAgICAgIiA8PCBjb25maWcuYmFz ZUROIDw8IGVuZGw7DQogICAgY291dCA8PCAiU2VhcmNoIFVzZXI6ICAiIDw8IGNvbmZpZy5zZWFy Y2hVc2VyIDw8IGVuZGw7DQogICAgY291dCA8PCAiVGhyZWFkczogICAgICAiIDw8IG51bVRocmVh ZHMgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICJEdXJhdGlvbjogICAgICIgPDwgZHVyYXRpb25NaW51 dGVzIDw8ICIgbWludXRlcyIgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICJDb25uZWN0aW9uOiAgIFNI QVJFRCBhY3Jvc3MgYWxsIHRocmVhZHMiIDw8IGVuZGw7DQogICAgY291dCA8PCAiPT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIiA8PCBlbmRsOw0KDQogICAgLy8gQ3Jl YXRlIHNoYXJlZCBMREFQIGJlbmNobWFyayBpbnN0YW5jZQ0KICAgIFNoYXJlZExEQVBCZW5jaG1h cmsgYmVuY2htYXJrKGNvbmZpZyk7DQoNCiAgICAvLyBJbml0aWFsaXplIExEQVAgY29ubmVjdGlv biBpbiBtYWluIHRocmVhZA0KICAgIGlmICghYmVuY2htYXJrLmluaXRpYWxpemUoKSkgew0KICAg ICAgICBjZXJyIDw8ICJGYWlsZWQgdG8gaW5pdGlhbGl6ZSBMREFQIGNvbm5lY3Rpb24iIDw8IGVu ZGw7DQogICAgICAgIHJldHVybiAxOw0KICAgIH0NCg0KICAgIGNvdXQgPDwgIlxuPT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICJM REFQIGNvbm5lY3Rpb24gaW5pdGlhbGl6ZWQgc3VjY2Vzc2Z1bGx5IiA8PCBlbmRsOw0KICAgIGNv dXQgPDwgIkFsbCAiIDw8IG51bVRocmVhZHMgPDwgIiB0aHJlYWRzIHdpbGwgc2hhcmUgdGhpcyBj b25uZWN0aW9uIiA8PCBlbmRsOw0KICAgIGNvdXQgPDwgIj09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT1cbiIgPDwgZW5kbDsNCg0KICAgIC8vIFNoYXJlZCBzdGF0aXN0aWNz IGFjcm9zcyBhbGwgdGhyZWFkcw0KICAgIE9wZXJhdGlvblN0YXRzIHN0YXRzMSwgc3RhdHMyLCBz dGF0czM7DQogICAgc3RhdHMxLm9wZXJhdGlvbk5hbWUgPSAiVGFzayAxOiBVc2VyIFNlYXJjaCAo bGRhcF9zZWFyY2hfZXh0X3MpIjsNCiAgICBzdGF0czIub3BlcmF0aW9uTmFtZSA9ICJUYXNrIDI6 IEZldGNoIFVJRCBBdHRyaWJ1dGUiOw0KICAgIHN0YXRzMy5vcGVyYXRpb25OYW1lID0gIlRhc2sg MzogRmV0Y2ggTmFtZSBBdHRyaWJ1dGUiOw0KDQogICAgYXRvbWljPGludD4gdG90YWxJdGVyYXRp b25zKDApOw0KDQogICAgY291dCA8PCAiU3RhcnRpbmcgIiA8PCBudW1UaHJlYWRzIDw8ICIgd29y a2VyIHRocmVhZHMuLi4iIDw8IGVuZGw7DQoNCiAgICBhdXRvIGJlbmNobWFya1N0YXJ0ID0gaGln aF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsNCg0KICAgIC8vIENyZWF0ZSBhbmQgbGF1bmNoIHRo cmVhZHMNCiAgICB2ZWN0b3I8dGhyZWFkPiB0aHJlYWRzOw0KICAgIGZvciAoaW50IGkgPSAwOyBp IDwgbnVtVGhyZWFkczsgaSsrKSB7DQogICAgICAgIHRocmVhZHMuZW1wbGFjZV9iYWNrKHRocmVh ZFdvcmtlciwNCiAgICAgICAgICAgIGkgKyAxLA0KICAgICAgICAgICAgJmJlbmNobWFyaywNCiAg ICAgICAgICAgIGR1cmF0aW9uTWludXRlcywNCiAgICAgICAgICAgIHJlZihzdGF0czEpLA0KICAg ICAgICAgICAgcmVmKHN0YXRzMiksDQogICAgICAgICAgICByZWYoc3RhdHMzKSwNCiAgICAgICAg ICAgIHJlZih0b3RhbEl0ZXJhdGlvbnMpKTsNCiAgICB9DQoNCiAgICAvLyBNb25pdG9yIHByb2dy ZXNzIHdoaWxlIHRocmVhZHMgYXJlIHJ1bm5pbmcNCiAgICBib29sIHRocmVhZHNSdW5uaW5nID0g dHJ1ZTsNCiAgICAvKnRocmVhZCBwcm9ncmVzc01vbml0b3IoWyZdKCkgew0KICAgICAgICBpbnQg bGFzdEl0ZXJhdGlvbnMgPSAwOw0KICAgICAgICB3aGlsZSAodGhyZWFkc1J1bm5pbmcpIHsNCiAg ICAgICAgICAgIHRoaXNfdGhyZWFkOjpzbGVlcF9mb3Ioc2Vjb25kcygxMCkpOw0KICAgICAgICAg ICAgaW50IGN1cnJlbnRJdGVyYXRpb25zID0gdG90YWxJdGVyYXRpb25zLmxvYWQoKTsNCiAgICAg ICAgICAgIGludCBpdGVyYXRpb25zUGVyU2Vjb25kID0gKGN1cnJlbnRJdGVyYXRpb25zIC0gbGFz dEl0ZXJhdGlvbnMpIC8gMTA7DQogICAgICAgICAgICBsYXN0SXRlcmF0aW9ucyA9IGN1cnJlbnRJ dGVyYXRpb25zOw0KDQogICAgICAgICAgICBpZiAodGhyZWFkc1J1bm5pbmcpIHsNCiAgICAgICAg ICAgICAgICBhdXRvIGVsYXBzZWQgPSBkdXJhdGlvbl9jYXN0PHNlY29uZHM+KGhpZ2hfcmVzb2x1 dGlvbl9jbG9jazo6bm93KCkgLSBiZW5jaG1hcmtTdGFydCk7DQogICAgICAgICAgICAgICAgY291 dCA8PCAiXG5bUHJvZ3Jlc3NdICIgPDwgZWxhcHNlZC5jb3VudCgpIDw8ICJzIGVsYXBzZWQsICIN CiAgICAgICAgICAgICAgICAgICAgIDw8IGN1cnJlbnRJdGVyYXRpb25zIDw8ICIgdG90YWwgaXRl cmF0aW9ucywgIg0KICAgICAgICAgICAgICAgICAgICAgPDwgaXRlcmF0aW9uc1BlclNlY29uZCA8 PCAiIG9wcy9zZWMgKGxhc3QgMTBzKSIgPDwgZW5kbDsNCiAgICAgICAgICAgIH0NCiAgICAgICAg fQ0KICAgIH0pOyovDQoNCiAgICAvLyBXYWl0IGZvciBhbGwgdGhyZWFkcyB0byBjb21wbGV0ZQ0K ICAgIGZvciAoYXV0byYgdCA6IHRocmVhZHMpIHsNCiAgICAgICAgdC5qb2luKCk7DQogICAgfQ0K DQogICAgdGhyZWFkc1J1bm5pbmcgPSBmYWxzZTsNCiAgICAvL3Byb2dyZXNzTW9uaXRvci5qb2lu KCk7DQoNCiAgICBhdXRvIGJlbmNobWFya0VuZCA9IGhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93 KCk7DQogICAgYXV0byB0b3RhbER1cmF0aW9uID0gZHVyYXRpb25fY2FzdDxzZWNvbmRzPihiZW5j aG1hcmtFbmQgLSBiZW5jaG1hcmtTdGFydCk7DQoNCiAgICBjb3V0IDw8ICJcbj09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iIDw8IGVuZGw7DQogICAgY291dCA8PCAiQmVu Y2htYXJrIENvbXBsZXRlZCEiIDw8IGVuZGw7DQogICAgY291dCA8PCAiPT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PSIgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICJUaHJlYWRz OiAgICAgICAgICAgICAgIiA8PCBudW1UaHJlYWRzIDw8IGVuZGw7DQogICAgY291dCA8PCAiQ29u bmVjdGlvbiBUeXBlOiAgICAgIFNIQVJFRCIgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICJUb3RhbCBE dXJhdGlvbjogICAgICAgIiA8PCB0b3RhbER1cmF0aW9uLmNvdW50KCkgPDwgIiBzZWNvbmRzIiA8 PCBlbmRsOw0KICAgIGNvdXQgPDwgIlRvdGFsIEl0ZXJhdGlvbnM6ICAgICAiIDw8IHRvdGFsSXRl cmF0aW9ucy5sb2FkKCkgPDwgZW5kbDsNCiAgICBjb3V0IDw8ICJPdmVyYWxsIFRocm91Z2hwdXQ6 ICAgIiA8PCBmaXhlZCA8PCBzZXRwcmVjaXNpb24oMikNCiAgICAgICAgPDwgKHRvdGFsSXRlcmF0 aW9ucy5sb2FkKCkgKiAzLjAgLyB0b3RhbER1cmF0aW9uLmNvdW50KCkpIDw8ICIgb3BzL3NlYyIg PDwgZW5kbDsNCiAgICBjb3V0IDw8ICI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09IiA8PCBlbmRsOw0KDQogICAgLy8gUHJpbnQgc3VtbWFyaWVzDQogICAgc3RhdHMxLnBy aW50U3VtbWFyeSgpOw0KICAgIHN0YXRzMi5wcmludFN1bW1hcnkoKTsNCiAgICBzdGF0czMucHJp bnRTdW1tYXJ5KCk7DQoNCiAgICByZXR1cm4gMDsNCn0= --000000000000f8603e064cd72409--