Lyogdmk6c2V0IHRzPTggc3RzPTQgc3c9NDoKICoKICogVklNIC0gVmkgSU1wcm92ZWQJCWJ5IEJyYW0gTW9vbGVuYWFyCiAqCQkJCUdVSS9Nb3RpZiBzdXBwb3J0IGJ5IFJvYmVydCBXZWJiCiAqCQkJCU1hY2ludG9zaCBwb3J0IGJ5IERhbnkgU3QtQW1hbnQKICoJCQkJCSAgICAgIGFuZCBBeGVsIEtpZWxob3JuCiAqCQkJCVBvcnQgdG8gTVBXIGJ5IEJlcm5oYXJkIFByn21tZXIKICoJCQkJSW5pdGlhbCBDYXJib24gcG9ydCBieSBBbW1vbiBTa2lkbW9yZQogKgogKiBEbyAiOmhlbHAgdWdhbmRhIiAgaW4gVmltIHRvIHJlYWQgY29weWluZyBhbmQgdXNhZ2UgY29uZGl0aW9ucy4KICogRG8gIjpoZWxwIGNyZWRpdHMiIGluIFZpbSB0byBzZWUgYSBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQuCiAqIFNlZSBSRUFETUUudHh0IGZvciBhbiBvdmVydmlldyBvZiB0aGUgVmltIHNvdXJjZSBjb2RlLgogKi8KCi8qCiAqIE5PVEVTOiAtIFZpbSA3KyBkb2VzIG5vdCBzdXBwb3J0IGNsYXNzaWMgTWFjT1MuIFBsZWFzZSB1c2UgVmltIDYueAogKgkgIC0gQ29tbWVudHMgbWVudGlvbmluZyBGQVEgcmVmZXIgdG8gdGhlIGJvb2s6CiAqCSAgICAiTWFjd29ybGQgTWFjIFByb2dyYW1taW5nIEZBUXMiIGZyb20gIklERyBCb29rcyIKICovCgovKgogKiBUT0RPOiBDaGFuZ2Ugc3RpbGwgdG8gbWVyZ2UgZnJvbSB0aGUgbWFjdmltJ3MgaURpc2sKICoKICogZXJyb3JfZ2EsIG1jaF9lcnJtc2csIE5hdmlnYXRpb24ncyBjaGFuZ2VzIGluIGd1aV9tY2hfYnJvd3NlCiAqIHVzZXMgb2YgTWVudUl0ZW1JbmRleCwgY2hhbmdlcyBpbiBndWlfbWNoX3NldF9zaGVsbHNpemUsCiAqIFNjcmFwTWFuYWdlciBlcnJvciBoYW5kbGluZy4KICogQ29tbWVudHMgYWJvdXQgZnVuY3Rpb24gcmVtYWluaW5nIHRvIENhcmJvbml6ZS4KICoKICovCgogLyogVE9ETyAoSnVzc2kpCiAgKiAgICogQ2xpcGJvYXJkIGRvZXMgbm90IHdvcmsgKGF0IGxlYXN0IHNvbWUgY2FzZXMpCiAgKiAgICogQVRTVSBmb250IHJlbmRlcmluZyBoYXMgc29tZSBwcm9ibGVtcwogICogICAqIEludmVzdGlnYXRlIGFuZCByZW1vdmUgZGVhZCBjb2RlICh0aGVyZSBpcyBzdGlsbCBsb3RzIG9mIHRoYXQpCiAgKi8KCiNpbmNsdWRlIDxEZXZpY2VzLmg+IC8qIGluY2x1ZGVkIGZpcnN0IHRvIGF2b2lkIENSIHByb2JsZW1zICovCiNpbmNsdWRlICJ2aW0uaCIKCiNkZWZpbmUgVVNFX0NBUkJPTklaRUQKI2RlZmluZSBVU0VfQUVWRU5UCQkvKiBFbmFibGUgQUVWRU5UICovCiN1bmRlZiBVU0VfT0ZGU0VURURfV0lORE9XCS8qIERlYnVnZ2luZyBmZWF0dXJlOiBzdGFydCBWaW0gd2luZG93IE9GRlNFVGVkICovCgovKiBDb21waWxlIGFzIENvZGVXYXJpb3IgRXh0ZXJuYWwgRWRpdG9yICovCiNpZiBkZWZpbmVkKEZFQVRfQ1dfRURJVE9SKSAmJiAhZGVmaW5lZChVU0VfQUVWRU5UKQojIGRlZmluZSBVU0VfQUVWRU5UIC8qIE5lZWQgQXBwbGUgRXZlbnQgU3VwcG9ydCAqLwojZW5kaWYKCi8qIFZpbSdzIFNjcmFwIGZsYXZvci4gKi8KI2RlZmluZSBWSU1TQ1JBUEZMQVZPUiAnVklNIScKI2lmZGVmIEZFQVRfTUJZVEUKIyBkZWZpbmUgU0NSQVBURVhURkxBVk9SIGtTY3JhcEZsYXZvclR5cGVVbmljb2RlCiNlbHNlCiMgZGVmaW5lIFNDUkFQVEVYVEZMQVZPUiBrU2NyYXBGbGF2b3JUeXBlVGV4dAojZW5kaWYKCnN0YXRpYyBFdmVudEhhbmRsZXJVUFAgbW91c2VXaGVlbEhhbmRsZXJVUFAgPSBOVUxMOwpTSW50MzIgZ01hY1N5c3RlbVZlcnNpb247CgojaWZkZWYgTUFDT1NfQ09OVkVSVAojIGRlZmluZSBVU0VfQ0FSQk9OS0VZSEFORExFUgpzdGF0aWMgRXZlbnRIYW5kbGVyVVBQIGtleUV2ZW50SGFuZGxlclVQUCA9IE5VTEw7CiNlbmRpZgoKCi8qIEluY2x1ZGUgc29tZSBmaWxlLiBUT0RPOiBtb3ZlIGludG8gb3NfbWFjLmggKi8KI2luY2x1ZGUgPE1lbnVzLmg+CiNpbmNsdWRlIDxSZXNvdXJjZXMuaD4KI2luY2x1ZGUgPFByb2Nlc3Nlcy5oPgojaWZkZWYgVVNFX0FFVkVOVAojIGluY2x1ZGUgPEFwcGxlRXZlbnRzLmg+CiMgaW5jbHVkZSA8QUVSZWdpc3RyeS5oPgojZW5kaWYKIyBpbmNsdWRlIDxHZXN0YWx0Lmg+CiNpZiBVTklWRVJTQUxfSU5URVJGQUNFU19WRVJTSU9OID49IDB4MDMzMAojIGluY2x1ZGUgPENvbnRyb2xEZWZpbml0aW9ucy5oPgojIGluY2x1ZGUgPE5hdmlnYXRpb24uaD4gIC8qIE5hdmlnYXRpb24gb25seSBwYXJ0IG9mID8/ICovCiNlbmRpZgoKLyogSGVscCBNYW5hZ2VyIChiYWxsb29uLmgsIEhNIHByZWZpeGVkIGZ1bmN0aW9ucykgYXJlIG5vdCBzdXBwb3J0ZWQKICogdW5kZXIgQ2FyYm9uIChKdXNzaSkgKi8KIyAgaWYgMAovKiBOZXcgSGVscCBJbnRlcmZhY2UgZm9yIE1hYywgbm90IGltcGxlbWVudGVkIHlldC4qLwojICAgIGluY2x1ZGUgPE1hY0hlbHAuaD4KIyAgZW5kaWYKCi8qCiAqIFRoZXNlIHNlZW0gdG8gYmUgcmVjdGFuZ2xlIG9wdGlvbnMuIFdoeSBhcmUgdGhleSBub3QgZm91bmQgaW4KICogaGVhZGVycz8gKEp1c3NpKQogKi8KI2RlZmluZSBrTm90aGluZyAwCiNkZWZpbmUga0NyZWF0ZUVtcHR5IDIgLyoxKi8KI2RlZmluZSBrQ3JlYXRlUmVjdCAyCiNkZWZpbmUga0Rlc3Ryb3kgMwoKLyoKICogRGFueTogRG9uJ3QgbGlrZSB0aG9zZS4uLgogKi8KI2RlZmluZSB0b3BMZWZ0KHIpCSgoKFBvaW50KikmKHIpKVswXSkKI2RlZmluZSBib3RSaWdodChyKQkoKChQb2ludCopJihyKSlbMV0pCgoKLyogVGltZSBvZiBsYXN0IG1vdXNlIGNsaWNrLCB0byBkZXRlY3QgZG91YmxlLWNsaWNrICovCnN0YXRpYyBsb25nIGxhc3RNb3VzZVRpY2sgPSAwOwoKLyogPz8/ICovCnN0YXRpYyBSZ25IYW5kbGUgY3Vyc29yUmduOwpzdGF0aWMgUmduSGFuZGxlIGRyYWdSZ247CnN0YXRpYyBSZWN0IGRyYWdSZWN0OwpzdGF0aWMgc2hvcnQgZHJhZ1JlY3RFbmJsOwpzdGF0aWMgc2hvcnQgZHJhZ1JlY3RDb250cm9sOwoKLyogVGhpcyB2YXJpYWJsZSBpcyBzZXQgd2hlbiB3YWl0aW5nIGZvciBhbiBldmVudCwgd2hpY2ggaXMgdGhlIG9ubHkgbW9tZW50CiAqIHNjcm9sbGJhciBkcmFnZ2luZyBjYW4gYmUgZG9uZSBkaXJlY3RseS4gIEl0J3Mgbm90IGFsbG93ZWQgd2hpbGUgY29tbWFuZHMKICogYXJlIGV4ZWN1dGVkLCBiZWNhdXNlIGl0IG1heSBtb3ZlIHRoZSBjdXJzb3IgYW5kIHRoYXQgbWF5IGNhdXNlIHVuZXhwZWN0ZWQKICogcHJvYmxlbXMgKGUuZy4sIHdoaWxlICI6cyIgaXMgd29ya2luZykuCiAqLwpzdGF0aWMgaW50IGFsbG93X3Njcm9sbGJhciA9IEZBTFNFOwoKLyogTGFzdCBtb3VzZSBjbGljayBjYXVzZWQgY29udGV4dHVhbCBtZW51LCAodG8gcHJvdmlkZSBwcm9wZXIgcmVsZWFzZSkgKi8Kc3RhdGljIHNob3J0IGNsaWNrSXNQb3B1cDsKCi8qIEZlZWRiYWNrIEFjdGlvbiBmb3IgU2Nyb2xsYmFyICovCkNvbnRyb2xBY3Rpb25VUFAgZ1Njcm9sbEFjdGlvbjsKQ29udHJvbEFjdGlvblVQUCBnU2Nyb2xsRHJhZzsKCi8qIEtlZXBpbmcgdHJhY2sgb2Ygd2hpY2ggc2Nyb2xsYmFyIGlzIGJlaW5nIGRyYWdnZWQgKi8Kc3RhdGljIENvbnRyb2xIYW5kbGUgZHJhZ2dlZF9zYiA9IE5VTEw7CgpzdGF0aWMgc3RydWN0CnsKICAgIEZNRm9udEZhbWlseSBmYW1pbHk7CiAgICBGTUZvbnRTaXplIHNpemU7CiAgICBGTUZvbnRTdHlsZSBzdHlsZTsKICAgIEJvb2xlYW4gaXNQYW5lbFZpc2libGU7Cn0gZ0ZvbnRQYW5lbEluZm8gPSB7IDAsIDAsIDAsIGZhbHNlIH07CgojaWZkZWYgTUFDT1NfQ09OVkVSVAojIGRlZmluZSBVU0VfQVRTVUlfRFJBV0lORwpBVFNVU3R5bGUgICBnRm9udFN0eWxlOwpCb29sZWFuCSAgICBnSXNGb250RmFsbGJhY2tTZXQ7CiNlbmRpZgoKLyogQ29sb3JzIE1hY3JvcyAqLwojZGVmaW5lIFJHQihyLGcsYikJKChyKSA8PCAxNikgKyAoKGcpIDw8IDgpICsgKGIpCiNkZWZpbmUgUmVkKGMpCQkoKGMgJiAweDAwRkYwMDAwKSA+PiAxNikKI2RlZmluZSBHcmVlbihjKQkoKGMgJiAweDAwMDBGRjAwKSA+PiAgOCkKI2RlZmluZSBCbHVlKGMpCQkoKGMgJiAweDAwMDAwMEZGKSA+PiAgMCkKCi8qIEtleSBtYXBwaW5nICovCgojZGVmaW5lIHZrX0VzYwkJMHgzNQkvKiAtPiAxQiAqLwoKI2RlZmluZSB2a19GMQkJMHg3QQkvKiAtPiAxMCAqLwojZGVmaW5lIHZrX0YyCQkweDc4ICAvKjB4NjMqLwojZGVmaW5lIHZrX0YzCQkweDYzICAvKjB4NzYqLwojZGVmaW5lIHZrX0Y0CQkweDc2ICAvKjB4NjAqLwojZGVmaW5lIHZrX0Y1CQkweDYwICAvKjB4NjEqLwojZGVmaW5lIHZrX0Y2CQkweDYxICAvKjB4NjIqLwojZGVmaW5lIHZrX0Y3CQkweDYyICAvKjB4NjMqLyAgLyo/Ki8KI2RlZmluZSB2a19GOAkJMHg2NAojZGVmaW5lIHZrX0Y5CQkweDY1CiNkZWZpbmUgdmtfRjEwCQkweDZECiNkZWZpbmUgdmtfRjExCQkweDY3CiNkZWZpbmUgdmtfRjEyCQkweDZGCiNkZWZpbmUgdmtfRjEzCQkweDY5CiNkZWZpbmUgdmtfRjE0CQkweDZCCiNkZWZpbmUgdmtfRjE1CQkweDcxCgojZGVmaW5lIHZrX0NscgkJMHg0NwkvKiAtPiAxQiAoRVNDKSAqLwojZGVmaW5lIHZrX0VudGVyCTB4NEMJLyogLT4gMDMgKi8KCiNkZWZpbmUgdmtfU3BhY2UJMHgzMQkvKiAtPiAyMCAqLwojZGVmaW5lIHZrX1RhYgkJMHgzMAkvKiAtPiAwOSAqLwojZGVmaW5lIHZrX1JldHVybgkweDI0CS8qIC0+IDBEICovCi8qIFRoaXMgaXMgd3JvbmcgZm9yIE9TWCwgd2hhdCBpcyBpdCBmb3I/ICovCiNkZWZpbmUgdmtfRGVsZXRlCTBYMDgJLyogLT4gMDggQmFja1NwYWNlICovCgojZGVmaW5lIHZrX0hlbHAJCTB4NzIJLyogLT4gMDUgKi8KI2RlZmluZSB2a19Ib21lCQkweDczCS8qIC0+IDAxICovCiNkZWZpbmUJdmtfUGFnZVVwCTB4NzQJLyogLT4gMEQgKi8KI2RlZmluZSB2a19Gd2REZWxldGUJMHg3NQkvKiAtPiA3RiAqLwojZGVmaW5lCXZrX0VuZAkJMHg3NwkvKiAtPiAwNCAqLwojZGVmaW5lIHZrX1BhZ2VEb3duCTB4NzkJLyogLT4gMEMgKi8KCiNkZWZpbmUgdmtfVXAJCTB4N0UJLyogLT4gMUUgKi8KI2RlZmluZSB2a19Eb3duCQkweDdECS8qIC0+IDFGICovCiNkZWZpbmUJdmtfTGVmdAkJMHg3QgkvKiAtPiAxQyAqLwojZGVmaW5lIHZrX1JpZ2h0CTB4N0MJLyogLT4gMUQgKi8KCiNkZWZpbmUgdmtfVW5kbwkJdmtfRjEKI2RlZmluZSB2a19DdXQJCXZrX0YyCiNkZWZpbmUJdmtfQ29weQkJdmtfRjMKI2RlZmluZQl2a19QYXN0ZQl2a19GNAojZGVmaW5lIHZrX1ByaW50U2NyZWVuCXZrX0YxMwojZGVmaW5lIHZrX1NDcm9sbExvY2sJdmtfRjE0CiNkZWZpbmUJdmtfUGF1c2UJdmtfRjE1CiNkZWZpbmUJdmtfTnVtTG9jawl2a19DbHIKI2RlZmluZSB2a19JbnNlcnQJdmtfSGVscAoKI2RlZmluZSBLZXlTeW0JY2hhcgoKc3RhdGljIHN0cnVjdAp7CiAgICBLZXlTeW0gIGtleV9zeW07CiAgICBjaGFyX3UgIHZpbV9jb2RlMDsKICAgIGNoYXJfdSAgdmltX2NvZGUxOwp9IHNwZWNpYWxfa2V5c1tdID0KewogICAge3ZrX1VwLAkJJ2snLCAndSd9LAogICAge3ZrX0Rvd24sCQknaycsICdkJ30sCiAgICB7dmtfTGVmdCwJCSdrJywgJ2wnfSwKICAgIHt2a19SaWdodCwJCSdrJywgJ3InfSwKCiAgICB7dmtfRjEsCQknaycsICcxJ30sCiAgICB7dmtfRjIsCQknaycsICcyJ30sCiAgICB7dmtfRjMsCQknaycsICczJ30sCiAgICB7dmtfRjQsCQknaycsICc0J30sCiAgICB7dmtfRjUsCQknaycsICc1J30sCiAgICB7dmtfRjYsCQknaycsICc2J30sCiAgICB7dmtfRjcsCQknaycsICc3J30sCiAgICB7dmtfRjgsCQknaycsICc4J30sCiAgICB7dmtfRjksCQknaycsICc5J30sCiAgICB7dmtfRjEwLAkJJ2snLCAnOyd9LAoKICAgIHt2a19GMTEsCQknRicsICcxJ30sCiAgICB7dmtfRjEyLAkJJ0YnLCAnMid9LAogICAge3ZrX0YxMywJCSdGJywgJzMnfSwKICAgIHt2a19GMTQsCQknRicsICc0J30sCiAgICB7dmtfRjE1LAkJJ0YnLCAnNSd9LAoKLyogIHtYS19IZWxwLAkJJyUnLCAnMSd9LCAqLwovKiAge1hLX1VuZG8sCQknJicsICc4J30sICovCi8qICB7WEtfQmFja1NwYWNlLAknaycsICdiJ30sICovCiNpZm5kZWYgTUFDT1NfWAogICAge3ZrX0RlbGV0ZSwJCSdrJywgJ2InfSwKI2VuZGlmCiAgICB7dmtfSW5zZXJ0LAkJJ2snLCAnSSd9LAogICAge3ZrX0Z3ZERlbGV0ZSwJJ2snLCAnRCd9LAogICAge3ZrX0hvbWUsCQknaycsICdoJ30sCiAgICB7dmtfRW5kLAkJJ0AnLCAnNyd9LAovKiAge1hLX1ByaW9yLAkJJ2snLCAnUCd9LCAqLwovKiAge1hLX05leHQsCQknaycsICdOJ30sICovCi8qICB7WEtfUHJpbnQsCQknJScsICc5J30sICovCgogICAge3ZrX1BhZ2VVcCwJCSdrJywgJ1AnfSwKICAgIHt2a19QYWdlRG93biwJJ2snLCAnTid9LAoKICAgIC8qIEVuZCBvZiBsaXN0IG1hcmtlcjogKi8KICAgIHsoS2V5U3ltKTAsCQkwLCAwfQp9OwoKLyoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIEZvcndhcmQgZGVjbGFyYXRpb24gKGZvciB0aG9zZSBuZWVkZWQpCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCiNpZmRlZiBVU0VfQUVWRU5UCk9TRXJyIEhhbmRsZVVudXNlZFBhcm1zKGNvbnN0IEFwcGxlRXZlbnQgKnRoZUFFdmVudCk7CiNlbmRpZgoKLyoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIENvbnZlcnNpb24gVXRpbGl0eQogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCgovKgogKiBDMlBhc2NhbF9zYXZlCiAqCiAqIEFsbG9jYXRlIG1lbW9yeSBhbmQgY29udmVydCB0aGUgQy1TdHJpbmcgcGFzc2VkIGluCiAqIGludG8gYSBwYXNjYWwgc3RyaW5nCiAqCiAqLwoKICAgIGNoYXJfdSAqCkMyUGFzY2FsX3NhdmUoY2hhcl91ICpDc3RyaW5nKQp7CiAgICBjaGFyX3UgICpQYXNjYWxTdHJpbmc7CiAgICBpbnQJICAgIGxlbjsKCiAgICBpZiAoQ3N0cmluZyA9PSBOVUxMKQoJcmV0dXJuIE5VTEw7CgogICAgbGVuID0gU1RSTEVOKENzdHJpbmcpOwoKICAgIGlmIChsZW4gPiAyNTUpIC8qIFRydW5jYXRlIGlmIG5lY2Vzc2FyeSAqLwoJbGVuID0gMjU1OwoKICAgIFBhc2NhbFN0cmluZyA9IGFsbG9jKGxlbiArIDEpOwogICAgaWYgKFBhc2NhbFN0cmluZyAhPSBOVUxMKQogICAgewoJbWNoX21lbW1vdmUoUGFzY2FsU3RyaW5nICsgMSwgQ3N0cmluZywgbGVuKTsKCVBhc2NhbFN0cmluZ1swXSA9IGxlbjsKICAgIH0KCiAgICByZXR1cm4gUGFzY2FsU3RyaW5nOwp9CgovKgogKiBDMlBhc2NhbF9zYXZlX2FuZF9yZW1vdmVfYmFja3NsYXNoCiAqCiAqIEFsbG9jYXRlIG1lbW9yeSBhbmQgY29udmVydCB0aGUgQy1TdHJpbmcgcGFzc2VkIGluCiAqIGludG8gYSBwYXNjYWwgc3RyaW5nLiBBbHNvIHJlbW92ZSB0aGUgYmFja3NsYXNoIGF0IHRoZSBzYW1lIHRpbWUKICoKICovCgogICAgY2hhcl91ICoKQzJQYXNjYWxfc2F2ZV9hbmRfcmVtb3ZlX2JhY2tzbGFzaChjaGFyX3UgKkNzdHJpbmcpCnsKICAgIGNoYXJfdSAgKlBhc2NhbFN0cmluZzsKICAgIGludAkgICAgbGVuOwogICAgY2hhcl91ICAqcCwgKmM7CgogICAgbGVuID0gU1RSTEVOKENzdHJpbmcpOwoKICAgIGlmIChsZW4gPiAyNTUpIC8qIFRydW5jYXRlIGlmIG5lY2Vzc2FyeSAqLwoJbGVuID0gMjU1OwoKICAgIFBhc2NhbFN0cmluZyA9IGFsbG9jKGxlbiArIDEpOwogICAgaWYgKFBhc2NhbFN0cmluZyAhPSBOVUxMKQogICAgewoJZm9yIChjID0gQ3N0cmluZywgcCA9IFBhc2NhbFN0cmluZysxLCBsZW4gPSAwOyAoKmMgIT0gMCkgJiYgKGxlbiA8IDI1NSk7IGMrKykKCXsKCSAgICBpZiAoKCpjID09ICdcXCcpICYmIChjWzFdICE9IDApKQoJICAgIHsKCQljKys7CgkgICAgfQoJICAgICpwID0gKmM7CgkgICAgcCsrOwoJICAgIGxlbisrOwoJfQoJUGFzY2FsU3RyaW5nWzBdID0gbGVuOwogICAgfQoKICAgIHJldHVybiBQYXNjYWxTdHJpbmc7Cn0KCi8qCiAqIENvbnZlcnQgdGhlIG1vZGlmaWVycyBvZiBhbiBFdmVudCBpbnRvIHZpbSdzIG1vZGlmaWVycyAobW91c2UpCiAqLwoKICAgIGludF91CkV2ZW50TW9kaWZpZXJzMlZpbU1vdXNlTW9kaWZpZXJzKEV2ZW50TW9kaWZpZXJzIG1hY01vZGlmaWVycykKewogICAgaW50X3UgdmltTW9kaWZpZXJzID0gMHgwMDsKCiAgICBpZiAobWFjTW9kaWZpZXJzICYgKHNoaWZ0S2V5IHwgcmlnaHRTaGlmdEtleSkpCgl2aW1Nb2RpZmllcnMgfD0gTU9VU0VfU0hJRlQ7CiAgICBpZiAobWFjTW9kaWZpZXJzICYgKGNvbnRyb2xLZXkgfCByaWdodENvbnRyb2xLZXkpKQoJdmltTW9kaWZpZXJzIHw9IE1PVVNFX0NUUkw7CiAgICBpZiAobWFjTW9kaWZpZXJzICYgKG9wdGlvbktleSB8IHJpZ2h0T3B0aW9uS2V5KSkKCXZpbU1vZGlmaWVycyB8PSBNT1VTRV9BTFQ7CiNpZiAwCiAgICAvKiBOb3QgeWV0IHN1cHBvcnRlZCAqLwogICAgaWYgKG1hY01vZGlmaWVycyAmIChjbWRLZXkpKSAvKiBUaGVyZSdzIG5vIHJpZ2h0Q21kS2V5ICovCgl2aW1Nb2RpZmllcnMgfD0gTU9VU0VfQ01EOwojZW5kaWYKICAgIHJldHVybiAodmltTW9kaWZpZXJzKTsKfQoKLyoKICogQ29udmVydCB0aGUgbW9kaWZpZXJzIG9mIGFuIEV2ZW50IGludG8gdmltJ3MgbW9kaWZpZXJzIChrZXlzKQogKi8KCiAgICBzdGF0aWMgaW50X3UKRXZlbnRNb2RpZmllcnMyVmltTW9kaWZpZXJzKEV2ZW50TW9kaWZpZXJzIG1hY01vZGlmaWVycykKewogICAgaW50X3UgdmltTW9kaWZpZXJzID0gMHgwMDsKCiAgICBpZiAobWFjTW9kaWZpZXJzICYgKHNoaWZ0S2V5IHwgcmlnaHRTaGlmdEtleSkpCgl2aW1Nb2RpZmllcnMgfD0gTU9EX01BU0tfU0hJRlQ7CiAgICBpZiAobWFjTW9kaWZpZXJzICYgKGNvbnRyb2xLZXkgfCByaWdodENvbnRyb2xLZXkpKQoJdmltTW9kaWZpZXJzIHw9IE1PRF9NQVNLX0NUUkw7CiAgICBpZiAobWFjTW9kaWZpZXJzICYgKG9wdGlvbktleSB8IHJpZ2h0T3B0aW9uS2V5KSkKCXZpbU1vZGlmaWVycyB8PSBNT0RfTUFTS19BTFQ7CiNpZmRlZiBVU0VfQ01EX0tFWQogICAgaWYgKG1hY01vZGlmaWVycyAmIChjbWRLZXkpKSAvKiBUaGVyZSdzIG5vIHJpZ2h0Q21kS2V5ICovCgl2aW1Nb2RpZmllcnMgfD0gTU9EX01BU0tfQ01EOwojZW5kaWYKICAgIHJldHVybiAodmltTW9kaWZpZXJzKTsKfQoKLyogQ29udmVydCBhIHN0cmluZyByZXByZXNlbnRpbmcgYSBwb2ludCBzaXplIGludG8gcGl4ZWxzLiBUaGUgc3RyaW5nIHNob3VsZAogKiBiZSBhIHBvc2l0aXZlIGRlY2ltYWwgbnVtYmVyLCB3aXRoIGFuIG9wdGlvbmFsIGRlY2ltYWwgcG9pbnQgKGVnLCAiMTIiLCBvcgogKiAiMTAuNSIpLiBUaGUgcGl4ZWwgdmFsdWUgaXMgcmV0dXJuZWQsIGFuZCBhIHBvaW50ZXIgdG8gdGhlIG5leHQgdW5jb252ZXJ0ZWQKICogY2hhcmFjdGVyIGlzIHN0b3JlZCBpbiAqZW5kLiBUaGUgZmxhZyAidmVydGljYWwiIHNheXMgd2hldGhlciB0aGlzCiAqIGNhbGN1bGF0aW9uIGlzIGZvciBhIHZlcnRpY2FsIChoZWlnaHQpIHNpemUgb3IgYSBob3Jpem9udGFsICh3aWR0aCkgb25lLgogKgogKiBGcm9tIGd1aV93NDguYwogKi8KICAgIHN0YXRpYyBpbnQKcG9pbnRzX3RvX3BpeGVscyhjaGFyX3UgKnN0ciwgY2hhcl91ICoqZW5kLCBpbnQgdmVydGljYWwpCnsKICAgIGludAkJcGl4ZWxzOwogICAgaW50CQlwb2ludHMgPSAwOwogICAgaW50CQlkaXZpc29yID0gMDsKCiAgICB3aGlsZSAoKnN0cikKICAgIHsKCWlmICgqc3RyID09ICcuJyAmJiBkaXZpc29yID09IDApCgl7CgkgICAgLyogU3RhcnQga2VlcGluZyBhIGRpdmlzb3IsIGZvciBsYXRlciAqLwoJICAgIGRpdmlzb3IgPSAxOwoJICAgIGNvbnRpbnVlOwoJfQoKCWlmICghaXNkaWdpdCgqc3RyKSkKCSAgICBicmVhazsKCglwb2ludHMgKj0gMTA7Cglwb2ludHMgKz0gKnN0ciAtICcwJzsKCWRpdmlzb3IgKj0gMTA7CgoJKytzdHI7CiAgICB9CgogICAgaWYgKGRpdmlzb3IgPT0gMCkKCWRpdmlzb3IgPSAxOwoKICAgIHBpeGVscyA9IHBvaW50cy9kaXZpc29yOwogICAgKmVuZCA9IHN0cjsKICAgIHJldHVybiBwaXhlbHM7Cn0KCiNpZmRlZiBNQUNPU19DT05WRVJUCi8qCiAqIERlbGV0ZXMgYWxsIHRyYWNlcyBvZiBhbnkgV2luZG93cy1zdHlsZSBtbmVtb25pYyB0ZXh0IChpbmNsdWRpbmcgYW55CiAqIHBhcmVudGhlc2VzKSBmcm9tIGEgbWVudSBpdGVtIGFuZCByZXR1cm5zIHRoZSBjbGVhbmVkIG1lbnUgaXRlbSB0aXRsZS4KICogVGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgcmVsZWFzaW5nIHRoZSByZXR1cm5lZCBzdHJpbmcuCiAqLwogICAgc3RhdGljIENGU3RyaW5nUmVmCm1lbnVfdGl0bGVfcmVtb3ZpbmdfbW5lbW9uaWModmltbWVudV9UICptZW51KQp7CiAgICBDRlN0cmluZ1JlZgkJbmFtZTsKICAgIHNpemVfdAkJbWVudVRpdGxlTGVuOwogICAgQ0ZJbmRleAkJZGlzcGxheUxlbjsKICAgIENGUmFuZ2UJCW1uZW1vbmljU3RhcnQ7CiAgICBDRlJhbmdlCQltbmVtb25pY0VuZDsKICAgIENGTXV0YWJsZVN0cmluZ1JlZgljbGVhbmVkTmFtZTsKCiAgICBtZW51VGl0bGVMZW4gPSBTVFJMRU4obWVudS0+ZG5hbWUpOwogICAgbmFtZSA9IG1hY19lbmNfdG9fY2ZzdHJpbmcobWVudS0+ZG5hbWUsIG1lbnVUaXRsZUxlbik7CgogICAgaWYgKG5hbWUpCiAgICB7CgkvKiBTaW1wbGUgbW5lbW9uaWMtcmVtb3ZhbCBhbGdvcml0aG0sIGFzc3VtZXMgc2luZ2xlIHBhcmVudGhlc2l6ZWQKCSAqIG1uZW1vbmljIGNoYXJhY3RlciB0b3dhcmRzIHRoZSBlbmQgb2YgdGhlIG1lbnUgdGV4dCAqLwoJbW5lbW9uaWNTdGFydCA9IENGU3RyaW5nRmluZChuYW1lLCBDRlNUUigiKCIpLCBrQ0ZDb21wYXJlQmFja3dhcmRzKTsKCWRpc3BsYXlMZW4gPSBDRlN0cmluZ0dldExlbmd0aChuYW1lKTsKCglpZiAobW5lbW9uaWNTdGFydC5sb2NhdGlvbiAhPSBrQ0ZOb3RGb3VuZAoJCSYmIChtbmVtb25pY1N0YXJ0LmxvY2F0aW9uICsgMikgPCBkaXNwbGF5TGVuCgkJJiYgQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJBdEluZGV4KG5hbWUsCgkJICAgICAgIG1uZW1vbmljU3RhcnQubG9jYXRpb24gKyAxKSA9PSAoVW5pQ2hhciltZW51LT5tbmVtb25pYykKCXsKCSAgICBpZiAoQ0ZTdHJpbmdGaW5kV2l0aE9wdGlvbnMobmFtZSwgQ0ZTVFIoIikiKSwKCQkJQ0ZSYW5nZU1ha2UobW5lbW9uaWNTdGFydC5sb2NhdGlvbiArIDEsCgkJCSAgICBkaXNwbGF5TGVuIC0gbW5lbW9uaWNTdGFydC5sb2NhdGlvbiAtIDEpLAoJCQlrQ0ZDb21wYXJlQmFja3dhcmRzLCAmbW5lbW9uaWNFbmQpICYmCgkJICAgIChtbmVtb25pY1N0YXJ0LmxvY2F0aW9uICsgMikgPT0gbW5lbW9uaWNFbmQubG9jYXRpb24pCgkgICAgewoJCWNsZWFuZWROYW1lID0gQ0ZTdHJpbmdDcmVhdGVNdXRhYmxlQ29weShOVUxMLCAwLCBuYW1lKTsKCQlpZiAoY2xlYW5lZE5hbWUpCgkJewoJCSAgICBDRlN0cmluZ0RlbGV0ZShjbGVhbmVkTmFtZSwKCQkJICAgIENGUmFuZ2VNYWtlKG1uZW1vbmljU3RhcnQubG9jYXRpb24sCgkJCQltbmVtb25pY0VuZC5sb2NhdGlvbiArIDEgLQoJCQkJbW5lbW9uaWNTdGFydC5sb2NhdGlvbikpOwoKCQkgICAgQ0ZSZWxlYXNlKG5hbWUpOwoJCSAgICBuYW1lID0gY2xlYW5lZE5hbWU7CgkJfQoJICAgIH0KCX0KICAgIH0KCiAgICByZXR1cm4gbmFtZTsKfQojZW5kaWYKCi8qCiAqIENvbnZlcnQgYSBsaXN0IG9mIEZTU3BlYyBhbGlhc2VzIGludG8gYSBsaXN0IG9mIGZ1bGxwYXRobmFtZQogKiBjaGFyYWN0ZXIgc3RyaW5ncy4KICovCgogICAgY2hhcl91ICoqCm5ld19mbmFtZXNfZnJvbV9BRURlc2MoQUVEZXNjICp0aGVMaXN0LCBsb25nICpudW1GaWxlcywgT1NFcnIgKmVycm9yKQp7CiAgICBjaGFyX3UJKipmbmFtZXMgPSBOVUxMOwogICAgT1NFcnIJbmV3RXJyb3I7CiAgICBsb25nCWZpbGVDb3VudDsKICAgIEZTU3BlYwlmaWxlVG9PcGVuOwogICAgbG9uZwlhY3R1YWxTaXplOwogICAgQUVLZXl3b3JkCWR1bW15S2V5d29yZDsKICAgIERlc2NUeXBlCWR1bW15VHlwZTsKCiAgICAvKiBHZXQgbnVtYmVyIG9mIGZpbGVzIGluIGxpc3QgKi8KICAgICplcnJvciA9IEFFQ291bnRJdGVtcyh0aGVMaXN0LCBudW1GaWxlcyk7CiAgICBpZiAoKmVycm9yKQogICAgewoJcmV0dXJuKGZuYW1lcyk7CiAgICB9CgogICAgLyogQWxsb2NhdGUgdGhlIHBvaW50ZXIgbGlzdCAqLwogICAgZm5hbWVzID0gKGNoYXJfdSAqKikgYWxsb2MoKm51bUZpbGVzICogc2l6ZW9mKGNoYXJfdSAqKSk7CgogICAgLyogRW1wdHkgb3V0IHRoZSBsaXN0ICovCiAgICBmb3IgKGZpbGVDb3VudCA9IDA7IGZpbGVDb3VudCA8ICpudW1GaWxlczsgZmlsZUNvdW50KyspCglmbmFtZXNbZmlsZUNvdW50XSA9IE5VTEw7CgogICAgLyogU2NhbiB0aGUgbGlzdCBvZiBGU1NwZWMgKi8KICAgIGZvciAoZmlsZUNvdW50ID0gMTsgZmlsZUNvdW50IDw9ICpudW1GaWxlczsgZmlsZUNvdW50KyspCiAgICB7CgkvKiBHZXQgdGhlIGFsaWFzIGZvciB0aGUgbnRoIGZpbGUsIGNvbnZlcnQgdG8gYW4gRlNTcGVjICovCgluZXdFcnJvciA9IEFFR2V0TnRoUHRyKHRoZUxpc3QsIGZpbGVDb3VudCwgdHlwZUZTUywKCQkJCSZkdW1teUtleXdvcmQsICZkdW1teVR5cGUsCgkJCQkoUHRyKSAmZmlsZVRvT3Blbiwgc2l6ZW9mKEZTU3BlYyksICZhY3R1YWxTaXplKTsKCWlmIChuZXdFcnJvcikKCXsKCSAgICAvKiBDYWxsZXIgaXMgYWJsZSB0byBjbGVhbiB1cCAqLwoJICAgIC8qIFRPRE86IFNob3VsZCBiZSBjbGVhbiB1cCBvciBub3Q/IEZvciBzYWZldHkuICovCgkgICAgcmV0dXJuKGZuYW1lcyk7Cgl9CgoJLyogQ29udmVydCB0aGUgRlNTcGVjIHRvIGEgcGF0aG5hbWUgKi8KCWZuYW1lc1tmaWxlQ291bnQgLSAxXSA9IEZ1bGxQYXRoRnJvbUZTU3BlY19zYXZlKGZpbGVUb09wZW4pOwogICAgfQoKICAgIHJldHVybiAoZm5hbWVzKTsKfQoKLyoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIENvZGVXYXJyaW9yIEV4dGVybmFsIEVkaXRvciBTdXBwb3J0CiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KI2lmZGVmIEZFQVRfQ1dfRURJVE9SCgovKgogKiBIYW5kbGUgdGhlIFdpbmRvdyBTZWFyY2ggZXZlbnQgZnJvbSBDb2RlV2FycmlvcgogKgogKiBEZXNjcmlwdGlvbgogKiAtLS0tLS0tLS0tLQogKgogKiBUaGUgSURFIHNlbmRzIHRoZSBXaW5kb3cgU2VhcmNoIEFwcGxlRXZlbnQgdG8gdGhlIGVkaXRvciB3aGVuIGl0CiAqIG5lZWRzIHRvIGtub3cgd2hldGhlciBhIHBhcnRpY3VsYXIgZmlsZSBpcyBvcGVuIGluIHRoZSBlZGl0b3IuCiAqCiAqIEV2ZW50IFJlcGx5CiAqIC0tLS0tLS0tLS0tCiAqCiAqIE5vbmUuIFB1dCBkYXRhIGluIHRoZSBsb2NhdGlvbiBzcGVjaWZpZWQgaW4gdGhlIHN0cnVjdHVyZSByZWNlaXZlZC4KICoKICogUmVtYXJrcwogKiAtLS0tLS0tCiAqCiAqIFdoZW4gdGhlIGVkaXRvciByZWNlaXZlcyB0aGlzIGV2ZW50LCBkZXRlcm1pbmUgd2hldGhlciB0aGUgc3BlY2lmaWVkCiAqIGZpbGUgaXMgb3Blbi4gSWYgaXQgaXMsIHJldHVybiB0aGUgbW9kaWZpY2F0aW9uIGRhdGUvdGltZSBmb3IgdGhhdCBmaWxlCiAqIGluIHRoZSBhcHByb3ByaWF0ZSBsb2NhdGlvbiBzcGVjaWZpZWQgaW4gdGhlIHN0cnVjdHVyZS4gSWYgdGhlIGZpbGUgaXMKICogbm90IG9wZW5lZCwgcHV0IHRoZSB2YWx1ZSBmbmZFcnIoZmlsZSBub3QgZm91bmQpIGluIHRoYXQgbG9jYXRpb24uCiAqCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgV2luZG93U2VhcmNoIFdpbmRvd1NlYXJjaDsKc3RydWN0IFdpbmRvd1NlYXJjaCAvKiBmb3IgaGFuZGxpbmcgY2xhc3MgJ0tBSEwnLCBldmVudCAnU1JDSCcsIGtleURpcmVjdE9iamVjdCB0eXBlQ2hhciovCnsKICAgIEZTU3BlYyB0aGVGaWxlOyAvLyBpZGVudGlmaWVzIHRoZSBmaWxlCiAgICBsb25nICp0aGVEYXRlOyAvLyB3aGVyZSB0byBwdXQgdGhlIG1vZGlmaWNhdGlvbiBkYXRlL3RpbWUKfTsKCiAgICBwYXNjYWwgT1NFcnIKSGFuZGxlX0tBSExfU1JDSF9BRSgKCWNvbnN0IEFwcGxlRXZlbnQgICAgKnRoZUFFdmVudCwKCUFwcGxlRXZlbnQJICAgICp0aGVSZXBseSwKCWxvbmcJCSAgICByZWZDb24pCnsKICAgIE9TRXJyCWVycm9yID0gbm9FcnI7CiAgICBidWZfVAkqYnVmOwogICAgaW50CQlmb3VuZEZpbGUgPSBmYWxzZTsKICAgIERlc2NUeXBlCXR5cGVDb2RlOwogICAgV2luZG93U2VhcmNoIFNlYXJjaERhdGE7CiAgICBTaXplCWFjdHVhbFNpemU7CgogICAgZXJyb3IgPSBBRUdldFBhcmFtUHRyKHRoZUFFdmVudCwga2V5RGlyZWN0T2JqZWN0LCB0eXBlQ2hhciwgJnR5cGVDb2RlLCAoUHRyKSAmU2VhcmNoRGF0YSwgc2l6ZW9mKFdpbmRvd1NlYXJjaCksICZhY3R1YWxTaXplKTsKICAgIGlmIChlcnJvcikKICAgIHsKCXJldHVybihlcnJvcik7CiAgICB9CgogICAgZXJyb3IgPSBIYW5kbGVVbnVzZWRQYXJtcyh0aGVBRXZlbnQpOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuKGVycm9yKTsKICAgIH0KCiAgICBmb3IgKGJ1ZiA9IGZpcnN0YnVmOyBidWYgIT0gTlVMTDsgYnVmID0gYnVmLT5iX25leHQpCglpZiAoYnVmLT5iX21sLm1sX21mcCAhPSBOVUxMCgkJJiYgU2VhcmNoRGF0YS50aGVGaWxlLnBhcklEID09IGJ1Zi0+Yl9GU1NwZWMucGFySUQKCQkmJiBTZWFyY2hEYXRhLnRoZUZpbGUubmFtZVswXSA9PSBidWYtPmJfRlNTcGVjLm5hbWVbMF0KCQkmJiBTVFJOQ01QKFNlYXJjaERhdGEudGhlRmlsZS5uYW1lLCBidWYtPmJfRlNTcGVjLm5hbWUsIGJ1Zi0+Yl9GU1NwZWMubmFtZVswXSArIDEpID09IDApCgkgICAgewoJCWZvdW5kRmlsZSA9IHRydWU7CgkJYnJlYWs7CgkgICAgfQoKICAgIGlmIChmb3VuZEZpbGUgPT0gZmFsc2UpCgkqU2VhcmNoRGF0YS50aGVEYXRlID0gZm5mRXJyOwogICAgZWxzZQoJKlNlYXJjaERhdGEudGhlRGF0ZSA9IGJ1Zi0+Yl9tdGltZTsKCiAgICByZXR1cm4gZXJyb3I7Cn07CgovKgogKiBIYW5kbGUgdGhlIE1vZGlmaWVkIChmcm9tIElERSB0byBFZGl0b3IpIGV2ZW50IGZyb20gQ29kZVdhcnJpb3IKICoKICogRGVzY3JpcHRpb24KICogLS0tLS0tLS0tLS0KICoKICogVGhlIElERSBzZW5kcyB0aGlzIGV2ZW50IHRvIHRoZSBleHRlcm5hbCBlZGl0b3Igd2hlbiBpdCB3YW50cyB0bwogKiBrbm93IHdoaWNoIGZpbGVzIHRoYXQgYXJlIG9wZW4gaW4gdGhlIGVkaXRvciBoYXZlIGJlZW4gbW9kaWZpZWQuCiAqCiAqIFBhcmFtZXRlcnMgICBOb25lLgogKiAtLS0tLS0tLS0tCiAqCiAqIEV2ZW50IFJlcGx5CiAqIC0tLS0tLS0tLS0tCiAqIFRoZSByZXBseSBmb3IgdGhpcyBldmVudCBpczoKICoKICoga2V5RGlyZWN0T2JqZWN0IHR5cGVBRUxpc3QgcmVxdWlyZWQKICogIGVhY2ggZWxlbWVudCBpbiB0aGUgbGlzdCBpcyBhIHN0cnVjdHVyZSBvZiB0eXBlQ2hhcgogKgogKiBSZW1hcmtzCiAqIC0tLS0tLS0KICoKICogV2hlbiBidWlsZGluZyB0aGUgcmVwbHkgZXZlbnQsIGluY2x1ZGUgb25lIGVsZW1lbnQgaW4gdGhlIGxpc3QgZm9yCiAqIGVhY2ggb3BlbiBmaWxlIHRoYXQgaGFzIGJlZW4gbW9kaWZpZWQuCiAqCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgTW9kaWZpY2F0aW9uSW5mbyBNb2RpZmljYXRpb25JbmZvOwpzdHJ1Y3QgTW9kaWZpY2F0aW9uSW5mbyAvKiBmb3IgcmVwbHlpbmcgdG8gY2xhc3MgJ0tBSEwnLCBldmVudCAnTU9EICcsIGtleURpcmVjdE9iamVjdCB0eXBlQUVMaXN0Ki8KewogICAgRlNTcGVjIHRoZUZpbGU7IC8vIGlkZW50aWZpZXMgdGhlIGZpbGUKICAgIGxvbmcgdGhlRGF0ZTsgLy8gdGhlIGRhdGUvdGltZSB0aGUgZmlsZSB3YXMgbGFzdCBtb2RpZmllZAogICAgc2hvcnQgc2F2ZWQ7IC8vIHNldCB0aGlzIHRvIHplcm8gd2hlbiByZXBseWluZywgdW51c2VkCn07CgogICAgcGFzY2FsIE9TRXJyCkhhbmRsZV9LQUhMX01PRF9BRSgKCWNvbnN0IEFwcGxlRXZlbnQgICAgKnRoZUFFdmVudCwKCUFwcGxlRXZlbnQJICAgICp0aGVSZXBseSwKCWxvbmcJCSAgICByZWZDb24pCnsKICAgIE9TRXJyCWVycm9yID0gbm9FcnI7CiAgICBBRURlc2NMaXN0CXJlcGx5TGlzdDsKICAgIGxvbmcJbnVtRmlsZXM7CiAgICBNb2RpZmljYXRpb25JbmZvIHRoZUZpbGU7CiAgICBidWZfVAkqYnVmOwoKICAgIHRoZUZpbGUuc2F2ZWQgPSAwOwoKICAgIGVycm9yID0gSGFuZGxlVW51c2VkUGFybXModGhlQUV2ZW50KTsKICAgIGlmIChlcnJvcikKICAgIHsKCXJldHVybihlcnJvcik7CiAgICB9CgogICAgLyogU2VuZCB0aGUgcmVwbHkgKi8KLyogIHJlcGx5T2JqZWN0LmRlc2NyaXB0b3JUeXBlID0gdHlwZU51bGw7CiAgICByZXBseU9iamVjdC5kYXRhSGFuZGxlICAgICA9IG5pbDsqLwoKLyogQUVDcmVhdGVEZXNjKHR5cGVDaGFyLCAoUHRyKSZ0aXRsZVsxXSwgdGl0bGVbMF0sICZkYXRhKSAqLwogICAgZXJyb3IgPSBBRUNyZWF0ZUxpc3QobmlsLCAwLCBmYWxzZSwgJnJlcGx5TGlzdCk7CiAgICBpZiAoZXJyb3IpCiAgICB7CglyZXR1cm4oZXJyb3IpOwogICAgfQoKI2lmIDAKICAgIGVycm9yID0gQUVDb3VudEl0ZW1zKCZyZXBseUxpc3QsICZudW1GaWxlcyk7CgogICAgLyogQUVQdXRLZXlEZXNjKCZyZXBseUxpc3QsIGtleUFFUG5qZWN0LCAmYURlc2MpCiAgICAgKiBBRVB1dEtleVB0cigmcmVwbHlMaXN0LCBrZXlBRVBvc2l0aW9uLCB0eXBlQ2hhciwgKFB0cikmdGhlVHlwZSwKICAgICAqIHNpemVvZihEZXNjVHlwZSkpCiAgICAgKi8KCiAgICAvKiBBRVB1dERlc2MgKi8KI2VuZGlmCgogICAgbnVtRmlsZXMgPSAwOwogICAgZm9yIChidWYgPSBmaXJzdGJ1ZjsgYnVmICE9IE5VTEw7IGJ1ZiA9IGJ1Zi0+Yl9uZXh0KQoJaWYgKGJ1Zi0+Yl9tbC5tbF9tZnAgIT0gTlVMTCkKCXsKCSAgICAvKiBBZGQgdGhpcyBmaWxlIHRvIHRoZSBsaXN0ICovCgkgICAgdGhlRmlsZS50aGVGaWxlID0gYnVmLT5iX0ZTU3BlYzsKCSAgICB0aGVGaWxlLnRoZURhdGUgPSBidWYtPmJfbXRpbWU7Ci8qCSAgICB0aGVGaWxlLnRoZURhdGUgPSB0aW1lKE5VTEwpICYgKHRpbWVfdCkgMHhGRkZGRkZGMDsgKi8KCSAgICBlcnJvciA9IEFFUHV0UHRyKCZyZXBseUxpc3QsIG51bUZpbGVzLCB0eXBlQ2hhciwgKFB0cikgJnRoZUZpbGUsIHNpemVvZih0aGVGaWxlKSk7Cgl9OwoKI2lmIDAKICAgIGVycm9yID0gQUVDb3VudEl0ZW1zKCZyZXBseUxpc3QsICZudW1GaWxlcyk7CiNlbmRpZgoKICAgIC8qIFdlIGNhbiBhZGQgZGF0YSBvbmx5IGlmIHNvbWV0aGluZyB0byByZXBseSAqLwogICAgZXJyb3IgPSBBRVB1dFBhcmFtRGVzYyh0aGVSZXBseSwga2V5RGlyZWN0T2JqZWN0LCAmcmVwbHlMaXN0KTsKCiAgICBpZiAocmVwbHlMaXN0LmRhdGFIYW5kbGUpCglBRURpc3Bvc2VEZXNjKCZyZXBseUxpc3QpOwoKICAgIHJldHVybiBlcnJvcjsKfTsKCi8qCiAqIEhhbmRsZSB0aGUgR2V0IFRleHQgZXZlbnQgZnJvbSBDb2RlV2FycmlvcgogKgogKiBEZXNjcmlwdGlvbgogKiAtLS0tLS0tLS0tLQogKgogKiBUaGUgSURFIHNlbmRzIHRoZSBHZXQgVGV4dCBBcHBsZUV2ZW50IHRvIHRoZSBlZGl0b3Igd2hlbiBpdCBuZWVkcwogKiB0aGUgc291cmNlIGNvZGUgZnJvbSBhIGZpbGUuIEZvciBleGFtcGxlLCB3aGVuIHRoZSB1c2VyIGlzc3VlcyBhCiAqIENoZWNrIFN5bnRheCBvciBDb21waWxlIGNvbW1hbmQsIHRoZSBjb21waWxlciBuZWVkcyBhY2Nlc3MgdG8KICogdGhlIHNvdXJjZSBjb2RlIGNvbnRhaW5lZCBpbiB0aGUgZmlsZS4KICoKICogRXZlbnQgUmVwbHkKICogLS0tLS0tLS0tLS0KICoKICogTm9uZS4gUHV0IGRhdGEgaW4gbG9jYXRpb25zIHNwZWNpZmllZCBpbiB0aGUgc3RydWN0dXJlIHJlY2VpdmVkLgogKgogKiBSZW1hcmtzCiAqIC0tLS0tLS0KICoKICogV2hlbiB0aGUgZWRpdG9yIHJlY2VpdmVzIHRoaXMgZXZlbnQsIGl0IG11c3Qgc2V0IHRoZSBzaXplIG9mIHRoZSBoYW5kbGUKICogaW4gdGhlVGV4dCB0byBmaXQgdGhlIGRhdGEgaW4gdGhlIGZpbGUuIEl0IG11c3QgdGhlbiBjb3B5IHRoZSBlbnRpcmUKICogY29udGVudHMgb2YgdGhlIHNwZWNpZmllZCBmaWxlIGludG8gdGhlIG1lbW9yeSBsb2NhdGlvbiBzcGVjaWZpZWQgaW4KICogdGhlVGV4dC4KICoKICovCgp0eXBlZGVmIHN0cnVjdCBDV19HZXRUZXh0IENXX0dldFRleHQ7CnN0cnVjdCBDV19HZXRUZXh0IC8qIGZvciBoYW5kbGluZyBjbGFzcyAnS0FITCcsIGV2ZW50ICdHVFRYJywga2V5RGlyZWN0T2JqZWN0IHR5cGVDaGFyKi8KewogICAgRlNTcGVjIHRoZUZpbGU7IC8qIGlkZW50aWZpZXMgdGhlIGZpbGUgKi8KICAgIEhhbmRsZSB0aGVUZXh0OyAvKiB0aGUgbG9jYXRpb24gd2hlcmUgeW91IHJldHVybiB0aGUgdGV4dCAobXVzdCBiZSByZXNpemVkIHByb3Blcmx5KSAqLwogICAgbG9uZyAqdW51c2VkOyAgIC8qIDAgKG5vdCB1c2VkKSAqLwogICAgbG9uZyAqdGhlRGF0ZTsgIC8qIHdoZXJlIHRvIHB1dCB0aGUgbW9kaWZpY2F0aW9uIGRhdGUvdGltZSAqLwp9OwoKICAgIHBhc2NhbCBPU0VycgpIYW5kbGVfS0FITF9HVFRYX0FFKAoJY29uc3QgQXBwbGVFdmVudCAgICAqdGhlQUV2ZW50LAoJQXBwbGVFdmVudAkgICAgKnRoZVJlcGx5LAoJbG9uZwkJICAgIHJlZkNvbikKewogICAgT1NFcnIJZXJyb3IgPSBub0VycjsKICAgIGJ1Zl9UCSpidWY7CiAgICBpbnQJCWZvdW5kRmlsZSA9IGZhbHNlOwogICAgRGVzY1R5cGUJdHlwZUNvZGU7CiAgICBDV19HZXRUZXh0CUdldFRleHREYXRhOwogICAgU2l6ZQlhY3R1YWxTaXplOwogICAgY2hhcl91CSpsaW5lOwogICAgY2hhcl91CSpmdWxsYnVmZmVyID0gTlVMTDsKICAgIGxvbmcJbGluZXNpemU7CiAgICBsb25nCWxpbmVTdGFydDsKICAgIGxvbmcJQnVmZmVyU2l6ZTsKICAgIGxvbmcJbGluZW5vOwoKICAgIGVycm9yID0gQUVHZXRQYXJhbVB0cih0aGVBRXZlbnQsIGtleURpcmVjdE9iamVjdCwgdHlwZUNoYXIsICZ0eXBlQ29kZSwgKFB0cikgJkdldFRleHREYXRhLCBzaXplb2YoR2V0VGV4dERhdGEpLCAmYWN0dWFsU2l6ZSk7CgogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuKGVycm9yKTsKICAgIH0KCiAgICBmb3IgKGJ1ZiA9IGZpcnN0YnVmOyBidWYgIT0gTlVMTDsgYnVmID0gYnVmLT5iX25leHQpCglpZiAoYnVmLT5iX21sLm1sX21mcCAhPSBOVUxMKQoJICAgIGlmIChHZXRUZXh0RGF0YS50aGVGaWxlLnBhcklEID09IGJ1Zi0+Yl9GU1NwZWMucGFySUQpCgkgICAgewoJCWZvdW5kRmlsZSA9IHRydWU7CgkJYnJlYWs7CgkgICAgfQoKICAgIGlmIChmb3VuZEZpbGUpCiAgICB7CglCdWZmZXJTaXplID0gMDsgLyogR2V0SGFuZGxlU2l6ZShHZXRUZXh0RGF0YS50aGVUZXh0KTsgKi8KCWZvciAobGluZW5vID0gMDsgbGluZW5vIDw9IGJ1Zi0+Yl9tbC5tbF9saW5lX2NvdW50OyBsaW5lbm8rKykKCXsKCSAgICAvKiBNdXN0IHVzZSB0aGUgcmlnaHQgYnVmZmVyICovCgkgICAgbGluZSA9IG1sX2dldF9idWYoYnVmLCAobGluZW5yX1QpIGxpbmVubywgRkFMU0UpOwoJICAgIGxpbmVzaXplID0gU1RSTEVOKGxpbmUpICsgMTsKCSAgICBsaW5lU3RhcnQgPSBCdWZmZXJTaXplOwoJICAgIEJ1ZmZlclNpemUgKz0gbGluZXNpemU7CgkgICAgLyogUmVzaXplIGhhbmRsZSB0byBsaW5lc2l6ZSsxIHRvIGluY2x1ZGUgdGhlIGxpbmVmZWVkICovCgkgICAgU2V0SGFuZGxlU2l6ZShHZXRUZXh0RGF0YS50aGVUZXh0LCBCdWZmZXJTaXplKTsKCSAgICBpZiAoR2V0SGFuZGxlU2l6ZShHZXRUZXh0RGF0YS50aGVUZXh0KSAhPSBCdWZmZXJTaXplKQoJICAgIHsKCQlicmVhazsgLyogU2ltcGxlIGhhbmRsaW5nIGZvciBub3cgKi8KCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlITG9jayhHZXRUZXh0RGF0YS50aGVUZXh0KTsKCQlmdWxsYnVmZmVyID0gKGNoYXJfdSAqKSAqR2V0VGV4dERhdGEudGhlVGV4dDsKCQlTVFJDUFkoKGNoYXJfdSAqKShmdWxsYnVmZmVyICsgbGluZVN0YXJ0KSwgbGluZSk7CgkJZnVsbGJ1ZmZlcltCdWZmZXJTaXplLTFdID0gJ1xyJzsKCQlIVW5sb2NrKEdldFRleHREYXRhLnRoZVRleHQpOwoJICAgIH0KCX0KCWlmIChmdWxsYnVmZmVyICE9IE5VTEwpCgl7CgkgICAgSExvY2soR2V0VGV4dERhdGEudGhlVGV4dCk7CgkgICAgZnVsbGJ1ZmZlcltCdWZmZXJTaXplLTFdID0gMDsKCSAgICBIVW5sb2NrKEdldFRleHREYXRhLnRoZVRleHQpOwoJfQoJaWYgKGZvdW5kRmlsZSA9PSBmYWxzZSkKCSAgICAqR2V0VGV4dERhdGEudGhlRGF0ZSA9IGZuZkVycjsKCWVsc2UKLyoJICAgICpHZXRUZXh0RGF0YS50aGVEYXRlID0gdGltZShOVUxMKSAmICh0aW1lX3QpIDB4RkZGRkZGRjA7Ki8KCSAgICAqR2V0VGV4dERhdGEudGhlRGF0ZSA9IGJ1Zi0+Yl9tdGltZTsKICAgIH0KCiAgICBlcnJvciA9IEhhbmRsZVVudXNlZFBhcm1zKHRoZUFFdmVudCk7CiAgICBpZiAoZXJyb3IpCiAgICB7CglyZXR1cm4oZXJyb3IpOwogICAgfQoKICAgIHJldHVybihlcnJvcik7Cn0KCi8qCiAqCiAqLwoKLyogVGFrZW4gZnJvbSBNb3JlQXBwbGVFdmVudHM6UHJvY2Vzc0hlbHBlcnMqLwogICAgcGFzY2FsCU9TRXJyCkZpbmRQcm9jZXNzQnlTaWduYXR1cmUoCgljb25zdCBPU1R5cGUJCXRhcmdldFR5cGUsCgljb25zdCBPU1R5cGUJCXRhcmdldENyZWF0b3IsCglQcm9jZXNzU2VyaWFsTnVtYmVyUHRyCXBzblB0cikKewogICAgT1NFcnIJYW5FcnIgPSBub0VycjsKICAgIEJvb2xlYW4JbG9va2luZ0ZvclByb2Nlc3MgPSB0cnVlOwoKICAgIFByb2Nlc3NJbmZvUmVjICBpbmZvUmVjOwoKICAgIGluZm9SZWMucHJvY2Vzc0luZm9MZW5ndGggPSBzaXplb2YoUHJvY2Vzc0luZm9SZWMpOwogICAgaW5mb1JlYy5wcm9jZXNzTmFtZSA9IG5pbDsKICAgIGluZm9SZWMucHJvY2Vzc0FwcFNwZWMgPSBuaWw7CgogICAgcHNuUHRyLT5sb3dMb25nT2ZQU04gPSBrTm9Qcm9jZXNzOwogICAgcHNuUHRyLT5oaWdoTG9uZ09mUFNOID0ga05vUHJvY2VzczsKCiAgICB3aGlsZSAobG9va2luZ0ZvclByb2Nlc3MpCiAgICB7CglhbkVyciA9IEdldE5leHRQcm9jZXNzKHBzblB0cik7CglpZiAoYW5FcnIgIT0gbm9FcnIpCgkgICAgbG9va2luZ0ZvclByb2Nlc3MgPSBmYWxzZTsKCWVsc2UKCXsKCSAgICBhbkVyciA9IEdldFByb2Nlc3NJbmZvcm1hdGlvbihwc25QdHIsICZpbmZvUmVjKTsKCSAgICBpZiAoKGFuRXJyID09IG5vRXJyKQoJCSAgICAmJiAoaW5mb1JlYy5wcm9jZXNzVHlwZSA9PSB0YXJnZXRUeXBlKQoJCSAgICAmJiAoaW5mb1JlYy5wcm9jZXNzU2lnbmF0dXJlID09IHRhcmdldENyZWF0b3IpKQoJCWxvb2tpbmdGb3JQcm9jZXNzID0gZmFsc2U7Cgl9CiAgICB9CgogICAgcmV0dXJuIGFuRXJyOwp9Ly9lbmQgRmluZFByb2Nlc3NCeVNpZ25hdHVyZQoKICAgIHZvaWQKU2VuZF9LQUhMX01PRF9BRShidWZfVCAqYnVmKQp7CiAgICBPU0VycglhbkVyciA9IG5vRXJyOwogICAgQUVEZXNjCXRhcmdldEFwcERlc2MgPSB7IHR5cGVOdWxsLCBuaWwgfTsKICAgIFByb2Nlc3NTZXJpYWxOdW1iZXIJICAgIHBzbiA9IHsga05vUHJvY2Vzcywga05vUHJvY2VzcyB9OwogICAgQXBwbGVFdmVudAl0aGVSZXBseSA9IHsgdHlwZU51bGwsIG5pbCB9OwogICAgQUVTZW5kTW9kZQlzZW5kTW9kZTsKICAgIEFwcGxlRXZlbnQgIHRoZUV2ZW50ID0ge3R5cGVOdWxsLCBuaWwgfTsKICAgIEFFSWRsZVVQUCAgIGlkbGVQcm9jVVBQID0gbmlsOwogICAgTW9kaWZpY2F0aW9uSW5mbyBNb2REYXRhOwoKCiAgICBhbkVyciA9IEZpbmRQcm9jZXNzQnlTaWduYXR1cmUoJ0FQUEwnLCAnQ1dJRScsICZwc24pOwogICAgaWYgKGFuRXJyID09IG5vRXJyKQogICAgewoJYW5FcnIgPSBBRUNyZWF0ZURlc2ModHlwZVByb2Nlc3NTZXJpYWxOdW1iZXIsICZwc24sCgkJCSAgICAgIHNpemVvZihQcm9jZXNzU2VyaWFsTnVtYmVyKSwgJnRhcmdldEFwcERlc2MpOwoKCWlmIChhbkVyciA9PSBub0VycikKCXsKCSAgICBhbkVyciA9IEFFQ3JlYXRlQXBwbGVFdmVudCggJ0tBSEwnLCAnTU9EICcsICZ0YXJnZXRBcHBEZXNjLAoJCQkJCWtBdXRvR2VuZXJhdGVSZXR1cm5JRCwga0FueVRyYW5zYWN0aW9uSUQsICZ0aGVFdmVudCk7Cgl9CgoJQUVEaXNwb3NlRGVzYygmdGFyZ2V0QXBwRGVzYyk7CgoJLyogQWRkIHRoZSBwYXJtcyAqLwoJTW9kRGF0YS50aGVGaWxlID0gYnVmLT5iX0ZTU3BlYzsKCU1vZERhdGEudGhlRGF0ZSA9IGJ1Zi0+Yl9tdGltZTsKCglpZiAoYW5FcnIgPT0gbm9FcnIpCgkgICAgYW5FcnIgPSBBRVB1dFBhcmFtUHRyKCZ0aGVFdmVudCwga2V5RGlyZWN0T2JqZWN0LCB0eXBlQ2hhciwgJk1vZERhdGEsIHNpemVvZihNb2REYXRhKSk7CgoJaWYgKGlkbGVQcm9jVVBQID09IG5pbCkKCSAgICBzZW5kTW9kZSA9IGtBRU5vUmVwbHk7CgllbHNlCgkgICAgc2VuZE1vZGUgPSBrQUVXYWl0UmVwbHk7CgoJaWYgKGFuRXJyID09IG5vRXJyKQoJICAgIGFuRXJyID0gQUVTZW5kKCZ0aGVFdmVudCwgJnRoZVJlcGx5LCBzZW5kTW9kZSwga0FFTm9ybWFsUHJpb3JpdHksIGtOb1RpbWVPdXQsIGlkbGVQcm9jVVBQLCBuaWwpOwoJaWYgKGFuRXJyID09IG5vRXJyICAmJiAgc2VuZE1vZGUgPT0ga0FFV2FpdFJlcGx5KQoJewovKgkgICAgYW5FcnIgPSAgQUVIR2V0SGFuZGxlckVycm9yKCZ0aGVSZXBseSk7Ki8KCX0KCSh2b2lkKSBBRURpc3Bvc2VEZXNjKCZ0aGVSZXBseSk7CiAgICB9Cn0KI2VuZGlmIC8qIEZFQVRfQ1dfRURJVE9SICovCgovKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQXBwbGUgRXZlbnQgSGFuZGxpbmcgcHJvY2VkdXJlCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KI2lmZGVmIFVTRV9BRVZFTlQKCi8qCiAqIEhhbmRsZSB0aGUgVW51c2VkIHBhcm1zIG9mIGFuIEFwcGxlRXZlbnQKICovCgogICAgT1NFcnIKSGFuZGxlVW51c2VkUGFybXMoY29uc3QgQXBwbGVFdmVudCAqdGhlQUV2ZW50KQp7CiAgICBPU0VycgllcnJvcjsKICAgIGxvbmcJYWN0dWFsU2l6ZTsKICAgIERlc2NUeXBlCWR1bW15VHlwZTsKICAgIEFFS2V5d29yZAltaXNzZWRLZXl3b3JkOwoKICAgIC8qIEdldCB0aGUgIm1pc3NlZCBrZXl3b3JkIiBhdHRyaWJ1dGUgZnJvbSB0aGUgQXBwbGVFdmVudC4gKi8KICAgIGVycm9yID0gQUVHZXRBdHRyaWJ1dGVQdHIodGhlQUV2ZW50LCBrZXlNaXNzZWRLZXl3b3JkQXR0ciwKCQkJICAgICAgdHlwZUtleXdvcmQsICZkdW1teVR5cGUsCgkJCSAgICAgIChQdHIpJm1pc3NlZEtleXdvcmQsIHNpemVvZihtaXNzZWRLZXl3b3JkKSwKCQkJICAgICAgJmFjdHVhbFNpemUpOwoKICAgIC8qIElmIHRoZSBkZXNjcmlwdG9yIGlzbid0IGZvdW5kLCB0aGVuIHdlIGdvdCB0aGUgcmVxdWlyZWQgcGFyYW1ldGVycy4gKi8KICAgIGlmIChlcnJvciA9PSBlcnJBRURlc2NOb3RGb3VuZCkKICAgIHsKCWVycm9yID0gbm9FcnI7CiAgICB9CiAgICBlbHNlCiAgICB7CiNpZiAwCgkvKiBXaHkgaXMgdGhpcyByZW1vdmVkPyAqLwoJZXJyb3IgPSBlcnJBRUV2ZW50Tm90SGFuZGxlZDsKI2VuZGlmCiAgICB9CgogICAgcmV0dXJuIGVycm9yOwp9CgoKLyoKICogSGFuZGxlIHRoZSBPRG9jIEFwcGxlRXZlbnQKICoKICogRGVhbHMgd2l0aCBhbGwgZmlsZXMgZHJhZ2dlZCB0byB0aGUgYXBwbGljYXRpb24gaWNvbi4KICoKICovCgp0eXBlZGVmIHN0cnVjdCBTZWxlY3Rpb25SYW5nZSBTZWxlY3Rpb25SYW5nZTsKc3RydWN0IFNlbGVjdGlvblJhbmdlIC8qIGZvciBoYW5kbGluZyBrQ29yZUNsYXNzRXZlbnQ6a09wZW5Eb2N1bWVudHM6a2V5QUVQb3NpdGlvbiB0eXBlQ2hhciAqLwp7CiAgICBzaG9ydCB1bnVzZWQxOyAvLyAwIChub3QgdXNlZCkKICAgIHNob3J0IGxpbmVOdW07IC8vIGxpbmUgdG8gc2VsZWN0ICg8MCB0byBzcGVjaWZ5IHJhbmdlKQogICAgbG9uZyBzdGFydFJhbmdlOyAvLyBzdGFydCBvZiBzZWxlY3Rpb24gcmFuZ2UgKGlmIGxpbmUgPCAwKQogICAgbG9uZyBlbmRSYW5nZTsgLy8gZW5kIG9mIHNlbGVjdGlvbiByYW5nZSAoaWYgbGluZSA8IDApCiAgICBsb25nIHVudXNlZDI7IC8vIDAgKG5vdCB1c2VkKQogICAgbG9uZyB0aGVEYXRlOyAvLyBtb2RpZmljYXRpb24gZGF0ZS90aW1lCn07CgovKiBUaGUgSURFIHVzZXMgdGhlIG9wdGlvbmFsIGtleUFFUG9zaXRpb24gcGFyYW1ldGVyIHRvIHRlbGwgdGhlIGVkLQogICBpdG9yIHRoZSBzZWxlY3Rpb24gcmFuZ2UuIElmIGxpbmVOdW0gaXMgemVybyBvciBncmVhdGVyLCBzY3JvbGwgdGhlIHRleHQKICAgdG8gdGhlIHNwZWNpZmllZCBsaW5lLiBJZiBsaW5lTnVtIGlzIGxlc3MgdGhhbiB6ZXJvLCB1c2UgdGhlIHZhbHVlcyBpbgogICBzdGFydFJhbmdlIGFuZCBlbmRSYW5nZSB0byBzZWxlY3QgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXJzLiBTY3JvbGwKICAgdGhlIHRleHQgdG8gZGlzcGxheSB0aGUgc2VsZWN0aW9uLiBJZiBsaW5lTnVtLCBzdGFydFJhbmdlLCBhbmQKICAgZW5kUmFuZ2UgYXJlIGFsbCBuZWdhdGl2ZSwgdGhlcmUgaXMgbm8gc2VsZWN0aW9uIHJhbmdlIHNwZWNpZmllZC4KICovCgogICAgcGFzY2FsIE9TRXJyCkhhbmRsZU9Eb2NBRShjb25zdCBBcHBsZUV2ZW50ICp0aGVBRXZlbnQsIEFwcGxlRXZlbnQgKnRoZVJlcGx5LCBsb25nIHJlZkNvbikKewogICAgLyoKICAgICAqIFRPRE86IENsZWFuIHVwIHRoZSBjb2RlIHdpdGggY29udmVydCB0aGUgQXBwbGVFdmVudCBpbnRvCiAgICAgKiAgICAgICBhICI6YXJncyIKICAgICAqLwogICAgT1NFcnIJZXJyb3IgPSBub0VycjsKLy8gICAgT1NFcnIJZmlyc3RFcnJvciA9IG5vRXJyOwovLyAgICBzaG9ydAludW1FcnJvcnMgPSAwOwogICAgQUVEZXNjCXRoZUxpc3Q7CiAgICBEZXNjVHlwZQl0eXBlQ29kZTsKICAgIGxvbmcJbnVtRmlsZXM7CiAvLyAgIGxvbmcJIGZpbGVDb3VudDsKICAgIGNoYXJfdQkqKmZuYW1lczsKLy8gICAgY2hhcl91CWZuYW1lWzI1Nl07CiAgICBTaXplCWFjdHVhbFNpemU7CiAgICBTZWxlY3Rpb25SYW5nZSB0aGVQb3NpdGlvbjsKICAgIHNob3J0CWdvdFBvc2l0aW9uID0gZmFsc2U7CiAgICBsb25nCWxudW07CgogICAgLyogdGhlIGRpcmVjdCBvYmplY3QgcGFyYW1ldGVyIGlzIHRoZSBsaXN0IG9mIGFsaWFzZXMgdG8gZmlsZXMgKG9uZSBvciBtb3JlKSAqLwogICAgZXJyb3IgPSBBRUdldFBhcmFtRGVzYyh0aGVBRXZlbnQsIGtleURpcmVjdE9iamVjdCwgdHlwZUFFTGlzdCwgJnRoZUxpc3QpOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuKGVycm9yKTsKICAgIH0KCgogICAgZXJyb3IgPSBBRUdldFBhcmFtUHRyKHRoZUFFdmVudCwga2V5QUVQb3NpdGlvbiwgdHlwZUNoYXIsICZ0eXBlQ29kZSwgKFB0cikgJnRoZVBvc2l0aW9uLCBzaXplb2YoU2VsZWN0aW9uUmFuZ2UpLCAmYWN0dWFsU2l6ZSk7CiAgICBpZiAoZXJyb3IgPT0gbm9FcnIpCglnb3RQb3NpdGlvbiA9IHRydWU7CiAgICBpZiAoZXJyb3IgPT0gZXJyQUVEZXNjTm90Rm91bmQpCgllcnJvciA9IG5vRXJyOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuKGVycm9yKTsKICAgIH0KCi8qCiAgICBlcnJvciA9IEFFR2V0UGFyYW1EZXNjKHRoZUFFdmVudCwga2V5QUVQb3NpdGlvbiwgdHlwZUNoYXIsICZ0aGVQb3NpdGlvbik7CgogICAgaWYgKF5lcnJvcikgdGhlbgogICAgewoJaWYgKHRoZVBvc2l0aW9uLmxpbmVOdW0gPj0gMCkKCXsKCSAgLy8gR290byB0aGlzIGxpbmUKCX0KCWVsc2UKCXsKCSAgLy8gU2V0IHRoZSByYW5nZSBjaGFyIHdpc2UKCX0KICAgIH0KICovCgoKI2lmZGVmIEZFQVRfVklTVUFMCiAgICByZXNldF9WSXN1YWwoKTsKI2VuZGlmCgogICAgZm5hbWVzID0gbmV3X2ZuYW1lc19mcm9tX0FFRGVzYygmdGhlTGlzdCwgJm51bUZpbGVzLCAmZXJyb3IpOwoKICAgIGlmIChlcnJvcikKICAgIHsKICAgICAgLyogVE9ETzogZW1wdHkgZm5hbWVzW10gZmlyc3QgKi8KICAgICAgdmltX2ZyZWUoZm5hbWVzKTsKICAgICAgcmV0dXJuIChlcnJvcik7CiAgICB9CgogICAgaWYgKHN0YXJ0aW5nID4gMCkKICAgIHsKCWludCBpOwoJY2hhcl91ICpwOwoKCS8qIHRoZXNlIGFyZSB0aGUgaW5pdGlhbCBmaWxlcyBkcm9wcGVkIG9uIHRoZSBWaW0gaWNvbiAqLwoJZm9yIChpID0gMCA7IGkgPCBudW1GaWxlczsgaSsrKQoJewoJICAgIGlmIChnYV9ncm93KCZnbG9iYWxfYWxpc3QuYWxfZ2EsIDEpID09IEZBSUwKCQkJCSAgICAgIHx8IChwID0gdmltX3N0cnNhdmUoZm5hbWVzW2ldKSkgPT0gTlVMTCkKCQltY2hfZXhpdCgyKTsKCSAgICBlbHNlCgkJYWxpc3RfYWRkKCZnbG9iYWxfYWxpc3QsIHAsIDIpOwoJfQoKCS8qIENoYW5nZSBkaXJlY3RvcnkgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBmaXJzdCBmaWxlLiAqLwoJaWYgKEdBUkdDT1VOVCA+IDAgJiYgdmltX2NoZGlyZmlsZShhbGlzdF9uYW1lKCZHQVJHTElTVFswXSkpID09IE9LKQoJICAgIHNob3J0ZW5fZm5hbWVzKFRSVUUpOwoKCWdvdG8gZmluaXNoZWQ7CiAgICB9CgogICAgLyogSGFuZGxlIHRoZSBkcm9wLCA6ZWRpdCB0byBnZXQgdG8gdGhlIGZpbGUgKi8KICAgIGhhbmRsZV9kcm9wKG51bUZpbGVzLCBmbmFtZXMsIEZBTFNFKTsKCiAgICAvKiBUT0RPOiBIYW5kbGUgdGhlIGdvdG8vc2VsZWN0IGxpbmUgbW9yZSBjbGVhbmx5ICovCiAgICBpZiAoKG51bUZpbGVzID09IDEpICYgKGdvdFBvc2l0aW9uKSkKICAgIHsKCWlmICh0aGVQb3NpdGlvbi5saW5lTnVtID49IDApCgl7CgkgICAgbG51bSA9IHRoZVBvc2l0aW9uLmxpbmVOdW0gKyAxOwoJLyogIG9hcC0+bW90aW9uX3R5cGUgPSBNTElORTsKCSAgICBzZXRwY21hcmsoKTsqLwoJICAgIGlmIChsbnVtIDwgMUwpCgkJbG51bSA9IDFMOwoJICAgIGVsc2UgaWYgKGxudW0gPiBjdXJidWYtPmJfbWwubWxfbGluZV9jb3VudCkKCQlsbnVtID0gY3VyYnVmLT5iX21sLm1sX2xpbmVfY291bnQ7CgkgICAgY3Vyd2luLT53X2N1cnNvci5sbnVtID0gbG51bTsKCSAgICBjdXJ3aW4tPndfY3Vyc29yLmNvbCA9IDA7CgkvKiAgYmVnaW5saW5lKEJMX1NPTCB8IEJMX0ZJWCk7Ki8KCX0KCWVsc2UKCSAgICBnb3RvX2J5dGUodGhlUG9zaXRpb24uc3RhcnRSYW5nZSArIDEpOwogICAgfQoKICAgIC8qIFVwZGF0ZSB0aGUgc2NyZWVuIGRpc3BsYXkgKi8KICAgIHVwZGF0ZV9zY3JlZW4oTk9UX1ZBTElEKTsKI2lmZGVmIEZFQVRfVklTVUFMCiAgICAvKiBTZWxlY3QgdGhlIHRleHQgaWYgcG9zc2libGUgKi8KICAgIGlmIChnb3RQb3NpdGlvbikKICAgIHsKCVZJc3VhbF9hY3RpdmUgPSBUUlVFOwoJVklzdWFsX3NlbGVjdCA9IEZBTFNFOwoJVklzdWFsID0gY3Vyd2luLT53X2N1cnNvcjsKCWlmICh0aGVQb3NpdGlvbi5saW5lTnVtIDwgMCkKCXsKCSAgICBWSXN1YWxfbW9kZSA9ICd2JzsKCSAgICBnb3RvX2J5dGUodGhlUG9zaXRpb24uZW5kUmFuZ2UpOwoJfQoJZWxzZQoJewoJICAgIFZJc3VhbF9tb2RlID0gJ1YnOwoJICAgIFZJc3VhbC5jb2wgPSAwOwoJfQogICAgfQojZW5kaWYKICAgIHNldGN1cnNvcigpOwogICAgb3V0X2ZsdXNoKCk7CgogICAgLyogRmFrZSBtb3VzZSBldmVudCB0byB3YWtlIGZyb20gc3RhbGwgKi8KICAgIFBvc3RFdmVudChtb3VzZVVwLCAwKTsKCiAgZmluaXNoZWQ6CiAgICBBRURpc3Bvc2VEZXNjKCZ0aGVMaXN0KTsgLyogZGlzcG9zZSB3aGF0IHdlIGFsbG9jYXRlZCAqLwoKICAgIGVycm9yID0gSGFuZGxlVW51c2VkUGFybXModGhlQUV2ZW50KTsKICAgIGlmIChlcnJvcikKICAgIHsKCXJldHVybihlcnJvcik7CiAgICB9CiAgICByZXR1cm4oZXJyb3IpOwp9CgovKgogKgogKi8KCiAgICBwYXNjYWwgT1NFcnIKSGFuZGxlX2FldnRfb2FwcF9BRSgKCWNvbnN0IEFwcGxlRXZlbnQgICAgKnRoZUFFdmVudCwKCUFwcGxlRXZlbnQJICAgICp0aGVSZXBseSwKCWxvbmcJCSAgICByZWZDb24pCnsKICAgIE9TRXJyCWVycm9yID0gbm9FcnI7CgogICAgZXJyb3IgPSBIYW5kbGVVbnVzZWRQYXJtcyh0aGVBRXZlbnQpOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuKGVycm9yKTsKICAgIH0KCiAgICByZXR1cm4oZXJyb3IpOwp9CgovKgogKgogKi8KCiAgICBwYXNjYWwgT1NFcnIKSGFuZGxlX2FldnRfcXVpdF9BRSgKCWNvbnN0IEFwcGxlRXZlbnQgICAgKnRoZUFFdmVudCwKCUFwcGxlRXZlbnQJICAgICp0aGVSZXBseSwKCWxvbmcJCSAgICByZWZDb24pCnsKICAgIE9TRXJyCWVycm9yID0gbm9FcnI7CgogICAgZXJyb3IgPSBIYW5kbGVVbnVzZWRQYXJtcyh0aGVBRXZlbnQpOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuKGVycm9yKTsKICAgIH0KCiAgICAvKiBOZWVkIHRvIGZha2UgYSA6Y29uZmlybSBxYSAqLwogICAgZG9fY21kbGluZV9jbWQoKGNoYXJfdSAqKSJjb25maXJtIHFhIik7CgogICAgcmV0dXJuKGVycm9yKTsKfQoKLyoKICoKICovCgogICAgcGFzY2FsIE9TRXJyCkhhbmRsZV9hZXZ0X3Bkb2NfQUUoCgljb25zdCBBcHBsZUV2ZW50ICAgICp0aGVBRXZlbnQsCglBcHBsZUV2ZW50CSAgICAqdGhlUmVwbHksCglsb25nCQkgICAgcmVmQ29uKQp7CiAgICBPU0VycgllcnJvciA9IG5vRXJyOwoKICAgIGVycm9yID0gSGFuZGxlVW51c2VkUGFybXModGhlQUV2ZW50KTsKICAgIGlmIChlcnJvcikKICAgIHsKCXJldHVybihlcnJvcik7CiAgICB9CgogICAgcmV0dXJuKGVycm9yKTsKfQoKLyoKICogSGFuZGxpbmcgb2YgdW5rbm93biBBcHBsZUV2ZW50CiAqCiAqIChKdXN0IGdldCByaWQgb2YgYWxsIHRoZSBwYXJtcykKICovCiAgICBwYXNjYWwgT1NFcnIKSGFuZGxlX3Vua25vd25fQUUoCgljb25zdCBBcHBsZUV2ZW50ICAgICp0aGVBRXZlbnQsCglBcHBsZUV2ZW50CSAgICAqdGhlUmVwbHksCglsb25nCQkgICAgcmVmQ29uKQp7CiAgICBPU0VycgllcnJvciA9IG5vRXJyOwoKICAgIGVycm9yID0gSGFuZGxlVW51c2VkUGFybXModGhlQUV2ZW50KTsKICAgIGlmIChlcnJvcikKICAgIHsKCXJldHVybihlcnJvcik7CiAgICB9CgogICAgcmV0dXJuKGVycm9yKTsKfQoKCi8qCiAqIEluc3RhbGwgdGhlIHZhcmlvdXMgQXBwbGVFdmVudCBIYW5kbGVycwogKi8KICAgIE9TRXJyCkluc3RhbGxBRUhhbmRsZXJzKHZvaWQpCnsKICAgIE9TRXJyICAgZXJyb3I7CgogICAgLyogaW5zdGFsbCBvcGVuIGFwcGxpY2F0aW9uIGhhbmRsZXIgKi8KICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKGtDb3JlRXZlbnRDbGFzcywga0FFT3BlbkFwcGxpY2F0aW9uLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfYWV2dF9vYXBwX0FFKSwgMCwgZmFsc2UpOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuIGVycm9yOwogICAgfQoKICAgIC8qIGluc3RhbGwgcXVpdCBhcHBsaWNhdGlvbiBoYW5kbGVyICovCiAgICBlcnJvciA9IEFFSW5zdGFsbEV2ZW50SGFuZGxlcihrQ29yZUV2ZW50Q2xhc3MsIGtBRVF1aXRBcHBsaWNhdGlvbiwKCQkgICAgTmV3QUVFdmVudEhhbmRsZXJVUFAoSGFuZGxlX2FldnRfcXVpdF9BRSksIDAsIGZhbHNlKTsKICAgIGlmIChlcnJvcikKICAgIHsKCXJldHVybiBlcnJvcjsKICAgIH0KCiAgICAvKiBpbnN0YWxsIG9wZW4gZG9jdW1lbnQgaGFuZGxlciAqLwogICAgZXJyb3IgPSBBRUluc3RhbGxFdmVudEhhbmRsZXIoa0NvcmVFdmVudENsYXNzLCBrQUVPcGVuRG9jdW1lbnRzLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVPRG9jQUUpLCAwLCBmYWxzZSk7CiAgICBpZiAoZXJyb3IpCiAgICB7CglyZXR1cm4gZXJyb3I7CiAgICB9CgogICAgLyogaW5zdGFsbCBwcmludCBkb2N1bWVudCBoYW5kbGVyICovCiAgICBlcnJvciA9IEFFSW5zdGFsbEV2ZW50SGFuZGxlcihrQ29yZUV2ZW50Q2xhc3MsIGtBRVByaW50RG9jdW1lbnRzLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfYWV2dF9wZG9jX0FFKSwgMCwgZmFsc2UpOwoKLyogSW5zdGFsbCBDb3JlIFN1aXRlICovCi8qICBlcnJvciA9IEFFSW5zdGFsbEV2ZW50SGFuZGxlcihrQUVDb3JlU3VpdGUsIGtBRUNsb25lLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfdW5rbm93bl9BRSksIG5pbCwgZmFsc2UpOwoKICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKGtBRUNvcmVTdWl0ZSwga0FFQ2xvc2UsCgkJICAgIE5ld0FFRXZlbnRIYW5kbGVyVVBQKEhhbmRsZV91bmtub3duX0FFKSwgbmlsLCBmYWxzZSk7CgogICAgZXJyb3IgPSBBRUluc3RhbGxFdmVudEhhbmRsZXIoa0FFQ29yZVN1aXRlLCBrQUVDb3VudEVsZW1lbnRzLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfdW5rbm93bl9BRSksIG5pbCwgZmFsc2UpOwoKICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKGtBRUNvcmVTdWl0ZSwga0FFQ3JlYXRlRWxlbWVudCwKCQkgICAgTmV3QUVFdmVudEhhbmRsZXJVUFAoSGFuZGxlX3Vua25vd25fQUUpLCBuaWwsIGZhbHNlKTsKCiAgICBlcnJvciA9IEFFSW5zdGFsbEV2ZW50SGFuZGxlcihrQUVDb3JlU3VpdGUsIGtBRURlbGV0ZSwKCQkgICAgTmV3QUVFdmVudEhhbmRsZXJVUFAoSGFuZGxlX3Vua25vd25fQUUpLCBuaWwsIGZhbHNlKTsKCiAgICBlcnJvciA9IEFFSW5zdGFsbEV2ZW50SGFuZGxlcihrQUVDb3JlU3VpdGUsIGtBRURvT2JqZWN0c0V4aXN0LAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfdW5rbm93bl9BRSksIG5pbCwgZmFsc2UpOwoKICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKGtBRUNvcmVTdWl0ZSwga0FFR2V0RGF0YSwKCQkgICAgTmV3QUVFdmVudEhhbmRsZXJVUFAoSGFuZGxlX3Vua25vd25fQUUpLCBrQUVHZXREYXRhLCBmYWxzZSk7CgogICAgZXJyb3IgPSBBRUluc3RhbGxFdmVudEhhbmRsZXIoa0FFQ29yZVN1aXRlLCBrQUVHZXREYXRhU2l6ZSwKCQkgICAgTmV3QUVFdmVudEhhbmRsZXJVUFAoSGFuZGxlX3Vua25vd25fQUUpLCBrQUVHZXREYXRhU2l6ZSwgZmFsc2UpOwoKICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKGtBRUNvcmVTdWl0ZSwga0FFR2V0Q2xhc3NJbmZvLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfdW5rbm93bl9BRSksIG5pbCwgZmFsc2UpOwoKICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKGtBRUNvcmVTdWl0ZSwga0FFR2V0RXZlbnRJbmZvLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfdW5rbm93bl9BRSksIG5pbCwgZmFsc2UpOwoKICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKGtBRUNvcmVTdWl0ZSwga0FFTW92ZSwKCQkgICAgTmV3QUVFdmVudEhhbmRsZXJVUFAoSGFuZGxlX3Vua25vd25fQUUpLCBuaWwsIGZhbHNlKTsKCiAgICBlcnJvciA9IEFFSW5zdGFsbEV2ZW50SGFuZGxlcihrQUVDb3JlU3VpdGUsIGtBRVNhdmUsCgkJICAgIE5ld0FFRXZlbnRIYW5kbGVyVVBQKEhhbmRsZV91bmtub3duX0FFKSwgbmlsLCBmYWxzZSk7CgogICAgZXJyb3IgPSBBRUluc3RhbGxFdmVudEhhbmRsZXIoa0FFQ29yZVN1aXRlLCBrQUVTZXREYXRhLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfdW5rbm93bl9BRSksIG5pbCwgZmFsc2UpOwoqLwoKI2lmZGVmIEZFQVRfQ1dfRURJVE9SCiAgICAvKgogICAgICogQmluZCBjb2Rld2FycmlvciBzdXBwb3J0IGhhbmRsZXJzCiAgICAgKi8KICAgIGVycm9yID0gQUVJbnN0YWxsRXZlbnRIYW5kbGVyKCdLQUhMJywgJ0dUVFgnLAoJCSAgICBOZXdBRUV2ZW50SGFuZGxlclVQUChIYW5kbGVfS0FITF9HVFRYX0FFKSwgMCwgZmFsc2UpOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuIGVycm9yOwogICAgfQogICAgZXJyb3IgPSBBRUluc3RhbGxFdmVudEhhbmRsZXIoJ0tBSEwnLCAnU1JDSCcsCgkJICAgIE5ld0FFRXZlbnRIYW5kbGVyVVBQKEhhbmRsZV9LQUhMX1NSQ0hfQUUpLCAwLCBmYWxzZSk7CiAgICBpZiAoZXJyb3IpCiAgICB7CglyZXR1cm4gZXJyb3I7CiAgICB9CiAgICBlcnJvciA9IEFFSW5zdGFsbEV2ZW50SGFuZGxlcignS0FITCcsICdNT0QgJywKCQkgICAgTmV3QUVFdmVudEhhbmRsZXJVUFAoSGFuZGxlX0tBSExfTU9EX0FFKSwgMCwgZmFsc2UpOwogICAgaWYgKGVycm9yKQogICAgewoJcmV0dXJuIGVycm9yOwogICAgfQojZW5kaWYKCiAgICByZXR1cm4gZXJyb3I7Cgp9CiNlbmRpZiAvKiBVU0VfQUVWRU5UICovCgoKLyoKICogQ2FsbGJhY2sgZnVuY3Rpb24sIGluc3RhbGxlZCBieSBJbnN0YWxsRm9udFBhbmVsSGFuZGxlcigpLCBiZWxvdywKICogdG8gaGFuZGxlIEZvbnQgUGFuZWwgZXZlbnRzLgogKi8KICAgIHN0YXRpYyBPU1N0YXR1cwpGb250UGFuZWxIYW5kbGVyKAoJRXZlbnRIYW5kbGVyQ2FsbFJlZiBpbkhhbmRsZXJDYWxsUmVmLAoJRXZlbnRSZWYgaW5FdmVudCwKCXZvaWQgKmluVXNlckRhdGEpCnsKICAgIGlmIChHZXRFdmVudEtpbmQoaW5FdmVudCkgPT0ga0V2ZW50Rm9udFBhbmVsQ2xvc2VkKQogICAgewoJZ0ZvbnRQYW5lbEluZm8uaXNQYW5lbFZpc2libGUgPSBmYWxzZTsKCXJldHVybiBub0VycjsKICAgIH0KCiAgICBpZiAoR2V0RXZlbnRLaW5kKGluRXZlbnQpID09IGtFdmVudEZvbnRTZWxlY3Rpb24pCiAgICB7CglPU1N0YXR1cyBzdGF0dXM7CglGTUZvbnRGYW1pbHkgbmV3RmFtaWx5OwoJRk1Gb250U2l6ZSBuZXdTaXplOwoJRk1Gb250U3R5bGUgbmV3U3R5bGU7CgoJLyogUmV0cmlldmUgdGhlIGZvbnQgZmFtaWx5IElEIG51bWJlci4gKi8KCXN0YXR1cyA9IEdldEV2ZW50UGFyYW1ldGVyKGluRXZlbnQsIGtFdmVudFBhcmFtRk1Gb250RmFtaWx5LAoJCS8qaW5EZXNpcmVkVHlwZT0qL3R5cGVGTUZvbnRGYW1pbHksIC8qb3V0QWN0dWFsVHlwZT0qL05VTEwsCgkJLyppbkJ1ZmZlclNpemU9Ki9zaXplb2YoRk1Gb250RmFtaWx5KSwgLypvdXRBY3R1YWxTaXplPSovTlVMTCwKCQkmbmV3RmFtaWx5KTsKCWlmIChzdGF0dXMgPT0gbm9FcnIpCgkgICAgZ0ZvbnRQYW5lbEluZm8uZmFtaWx5ID0gbmV3RmFtaWx5OwoKCS8qIFJldHJpZXZlIHRoZSBmb250IHNpemUuICovCglzdGF0dXMgPSBHZXRFdmVudFBhcmFtZXRlcihpbkV2ZW50LCBrRXZlbnRQYXJhbUZNRm9udFNpemUsCgkJdHlwZUZNRm9udFNpemUsIE5VTEwsIHNpemVvZihGTUZvbnRTaXplKSwgTlVMTCwgJm5ld1NpemUpOwoJaWYgKHN0YXR1cyA9PSBub0VycikKCSAgICBnRm9udFBhbmVsSW5mby5zaXplID0gbmV3U2l6ZTsKCgkvKiBSZXRyaWV2ZSB0aGUgZm9udCBzdHlsZSAoYm9sZCwgZXRjLikuICBDdXJyZW50bHkgdW51c2VkLiAqLwoJc3RhdHVzID0gR2V0RXZlbnRQYXJhbWV0ZXIoaW5FdmVudCwga0V2ZW50UGFyYW1GTUZvbnRTdHlsZSwKCQl0eXBlRk1Gb250U3R5bGUsIE5VTEwsIHNpemVvZihGTUZvbnRTdHlsZSksIE5VTEwsICZuZXdTdHlsZSk7CglpZiAoc3RhdHVzID09IG5vRXJyKQoJICAgIGdGb250UGFuZWxJbmZvLnN0eWxlID0gbmV3U3R5bGU7CiAgICB9CiAgICByZXR1cm4gbm9FcnI7Cn0KCgogICAgc3RhdGljIHZvaWQKSW5zdGFsbEZvbnRQYW5lbEhhbmRsZXIodm9pZCkKewogICAgRXZlbnRUeXBlU3BlYyBldmVudFR5cGVzWzJdOwogICAgRXZlbnRIYW5kbGVyVVBQIGhhbmRsZXJVUFA7CiAgICAvKiBFdmVudEhhbmRsZXJSZWYgaGFuZGxlclJlZjsgKi8KCiAgICBldmVudFR5cGVzWzBdLmV2ZW50Q2xhc3MgPSBrRXZlbnRDbGFzc0ZvbnQ7CiAgICBldmVudFR5cGVzWzBdLmV2ZW50S2luZCAgPSBrRXZlbnRGb250U2VsZWN0aW9uOwogICAgZXZlbnRUeXBlc1sxXS5ldmVudENsYXNzID0ga0V2ZW50Q2xhc3NGb250OwogICAgZXZlbnRUeXBlc1sxXS5ldmVudEtpbmQgID0ga0V2ZW50Rm9udFBhbmVsQ2xvc2VkOwoKICAgIGhhbmRsZXJVUFAgPSBOZXdFdmVudEhhbmRsZXJVUFAoRm9udFBhbmVsSGFuZGxlcik7CgogICAgSW5zdGFsbEFwcGxpY2F0aW9uRXZlbnRIYW5kbGVyKGhhbmRsZXJVUFAsIC8qbnVtVHlwZXM9Ki8yLCBldmVudFR5cGVzLAoJICAgIC8qdXNlckRhdGE9Ki9OVUxMLCAvKmhhbmRsZXJSZWY9Ki9OVUxMKTsKfQoKCi8qCiAqIEZpbGwgdGhlIGJ1ZmZlciBwb2ludGVkIHRvIGJ5IG91dE5hbWUgd2l0aCB0aGUgbmFtZSBhbmQgc2l6ZQogKiBvZiB0aGUgZm9udCBjdXJyZW50bHkgc2VsZWN0ZWQgaW4gdGhlIEZvbnQgUGFuZWwuCiAqLwojZGVmaW5lIEZPTlRfU1RZTEVfQlVGRkVSX1NJWkUgMzIKICAgIHN0YXRpYyB2b2lkCkdldEZvbnRQYW5lbFNlbGVjdGlvbihjaGFyX3UgKm91dE5hbWUpCnsKICAgIFN0cjI1NQkgICAgYnVmOwogICAgQnl0ZUNvdW50CSAgICBmb250TmFtZUxlbiA9IDA7CiAgICBBVFNVRm9udElECSAgICBmaWQ7CiAgICBjaGFyX3UJICAgIHN0eWxlU3RyaW5nW0ZPTlRfU1RZTEVfQlVGRkVSX1NJWkVdOwoKICAgIGlmICghb3V0TmFtZSkKCXJldHVybjsKCiAgICBpZiAoRk1HZXRGb250RmFtaWx5TmFtZShnRm9udFBhbmVsSW5mby5mYW1pbHksIGJ1ZikgPT0gbm9FcnIpCiAgICB7CgkvKiBDYW5vbmljYWxpemUgbG9jYWxpemVkIGZvbnQgbmFtZXMgKi8KCWlmIChGTUdldEZvbnRGcm9tRm9udEZhbWlseUluc3RhbmNlKGdGb250UGFuZWxJbmZvLmZhbWlseSwKCQkgICAgZ0ZvbnRQYW5lbEluZm8uc3R5bGUsICZmaWQsIE5VTEwpICE9IG5vRXJyKQoJICAgIHJldHVybjsKCgkvKiBSZXF1ZXN0IGZvbnQgbmFtZSB3aXRoIE1hYyBlbmNvZGluZyAob3RoZXJ3aXNlIHdlIGNvdWxkCgkgKiBnZXQgYW4gdW53YW50ZWQgdXRmLTE2IG5hbWUpICovCglpZiAoQVRTVUZpbmRGb250TmFtZShmaWQsIGtGb250RnVsbE5hbWUsIGtGb250TWFjaW50b3NoUGxhdGZvcm0sCgkJICAgIGtGb250Tm9TY3JpcHRDb2RlLCBrRm9udE5vTGFuZ3VhZ2VDb2RlLAoJCSAgICAyNTUsIChjaGFyICopb3V0TmFtZSwgJmZvbnROYW1lTGVuLCBOVUxMKSAhPSBub0VycikKCSAgICByZXR1cm47CgoJLyogT25seSBlbmNvZGUgZm9udCBzaXplLCBiZWNhdXNlIHN0eWxlIChib2xkLCBpdGFsaWMsIGV0YykgaXMKCSAqIGFscmVhZHkgcGFydCBvZiB0aGUgZm9udCBmdWxsIG5hbWUgKi8KCXZpbV9zbnByaW50ZigoY2hhciAqKXN0eWxlU3RyaW5nLCBGT05UX1NUWUxFX0JVRkZFUl9TSVpFLCAiOmglZCIsCgkJZ0ZvbnRQYW5lbEluZm8uc2l6ZS8qLAoJCSgoZ0ZvbnRQYW5lbEluZm8uc3R5bGUgJiBib2xkKSE9MCA/ICI6YiIgOiAiIiksCgkJKChnRm9udFBhbmVsSW5mby5zdHlsZSAmIGl0YWxpYykhPTAgPyAiOmkiIDogIiIpLAoJCSgoZ0ZvbnRQYW5lbEluZm8uc3R5bGUgJiB1bmRlcmxpbmUpIT0wID8gIjp1IiA6ICIiKSovKTsKCglpZiAoKGZvbnROYW1lTGVuICsgU1RSTEVOKHN0eWxlU3RyaW5nKSkgPCAyNTUpCgkgICAgU1RSQ1BZKG91dE5hbWUgKyBmb250TmFtZUxlbiwgc3R5bGVTdHJpbmcpOwogICAgfQogICAgZWxzZQogICAgewoJKm91dE5hbWUgPSBOVUw7CiAgICB9Cn0KCgovKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogVW5maWxlZCB5ZXQKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKLyoKICogIGd1aV9tYWNfZ2V0X21lbnVfaXRlbV9pbmRleAogKgogKiAgUmV0dXJucyB0aGUgaW5kZXggaW5zaWRlIHRoZSBtZW51IHdoZXIKICovCiAgICBzaG9ydCAvKiBTaG91bGRlIHdlIHJldHVybiBNZW51SXRlbUluZGV4PyAqLwpndWlfbWFjX2dldF9tZW51X2l0ZW1faW5kZXgodmltbWVudV9UICpwTWVudSkKewogICAgc2hvcnQJaW5kZXg7CiAgICBzaG9ydAlpdGVtSW5kZXggPSAtMTsKICAgIHZpbW1lbnVfVAkqcEJyb3RoZXI7CgogICAgLyogT25seSBtZW51IHdpdGhvdXQgcGFyZW50IGFyZSB0aGU6CiAgICAgKiAtbWVudSBpbiB0aGUgbWVudWJhcgogICAgICogLXBvcHVwIG1lbnUKICAgICAqIC10b29sYmFyIChndWVzcykKICAgICAqCiAgICAgKiBXaGljaCBhcmUgbm90IGl0ZW1zIGFueXdheS4KICAgICAqLwogICAgaWYgKHBNZW51LT5wYXJlbnQpCiAgICB7CgkvKiBTdGFydCBmcm9tIHRoZSBPbGRlc3QgQnJvdGhlciAqLwoJcEJyb3RoZXIgPSBwTWVudS0+cGFyZW50LT5jaGlsZHJlbjsKCWluZGV4ID0gMTsKCXdoaWxlICgocEJyb3RoZXIpICYmIChpdGVtSW5kZXggPT0gLTEpKQoJewoJICAgIGlmIChwQnJvdGhlciA9PSBwTWVudSkKCQlpdGVtSW5kZXggPSBpbmRleDsKCSAgICBpbmRleCsrOwoJICAgIHBCcm90aGVyID0gcEJyb3RoZXItPm5leHQ7Cgl9CiAgICB9CiAgICByZXR1cm4gaXRlbUluZGV4Owp9CgogICAgc3RhdGljIHZpbW1lbnVfVCAqCmd1aV9tYWNfZ2V0X3ZpbV9tZW51KHNob3J0IG1lbnVJRCwgc2hvcnQgaXRlbUluZGV4LCB2aW1tZW51X1QgKnBNZW51KQp7CiAgICBzaG9ydAlpbmRleDsKICAgIHZpbW1lbnVfVAkqcENoaWxkTWVudTsKICAgIHZpbW1lbnVfVAkqcEVsZGVyID0gcE1lbnUtPnBhcmVudDsKCgogICAgLyogT25seSBtZW51IHdpdGhvdXQgcGFyZW50IGFyZSB0aGU6CiAgICAgKiAtbWVudSBpbiB0aGUgbWVudWJhcgogICAgICogLXBvcHVwIG1lbnUKICAgICAqIC10b29sYmFyIChndWVzcykKICAgICAqCiAgICAgKiBXaGljaCBhcmUgbm90IGl0ZW1zIGFueXdheS4KICAgICAqLwoKICAgIGlmICgocEVsZGVyKSAmJiAocEVsZGVyLT5zdWJtZW51X2lkID09IG1lbnVJRCkpCiAgICB7Cglmb3IgKGluZGV4ID0gMTsgKGluZGV4ICE9IGl0ZW1JbmRleCkgJiYgKHBNZW51ICE9IE5VTEwpOyBpbmRleCsrKQoJICAgIHBNZW51ID0gcE1lbnUtPm5leHQ7CiAgICB9CiAgICBlbHNlCiAgICB7Cglmb3IgKDsgcE1lbnUgIT0gTlVMTDsgcE1lbnUgPSBwTWVudS0+bmV4dCkKCXsKCSAgICBpZiAocE1lbnUtPmNoaWxkcmVuICE9IE5VTEwpCgkgICAgewoJCXBDaGlsZE1lbnUgPSBndWlfbWFjX2dldF92aW1fbWVudQoJCQkgICAobWVudUlELCBpdGVtSW5kZXgsIHBNZW51LT5jaGlsZHJlbik7CgkJaWYgKHBDaGlsZE1lbnUpCgkJewoJCSAgICBwTWVudSA9IHBDaGlsZE1lbnU7CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gcE1lbnU7Cn0KCi8qCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBNYWNPUyBGZWVkYmFjayBwcm9jZWR1cmVzCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KICAgIHBhc2NhbAogICAgdm9pZApndWlfbWFjX2RyYWdfdGh1bWIoQ29udHJvbEhhbmRsZSB0aGVDb250cm9sLCBzaG9ydCBwYXJ0Q29kZSkKewogICAgc2Nyb2xsYmFyX1QJCSpzYjsKICAgIGludAkJCXZhbHVlLCBkcmFnZ2luZzsKICAgIENvbnRyb2xIYW5kbGUJdGhlQ29udHJvbFRvVXNlOwogICAgaW50CQkJZG9udF9zY3JvbGxfc2F2ZSA9IGRvbnRfc2Nyb2xsOwoKICAgIHRoZUNvbnRyb2xUb1VzZSA9IGRyYWdnZWRfc2I7CgogICAgc2IgPSBndWlfZmluZF9zY3JvbGxiYXIoKGxvbmcpIEdldENvbnRyb2xSZWZlcmVuY2UodGhlQ29udHJvbFRvVXNlKSk7CgogICAgaWYgKHNiID09IE5VTEwpCglyZXR1cm47CgogICAgLyogTmVlZCB0byBmaW5kIHZhbHVlIGJ5IGRpZmYgYmV0d2VlbiBPbGQgUG9zcyBOZXcgUG9zICovCiAgICB2YWx1ZSA9IEdldENvbnRyb2wzMkJpdFZhbHVlKHRoZUNvbnRyb2xUb1VzZSk7CiAgICBkcmFnZ2luZyA9IChwYXJ0Q29kZSAhPSAwKTsKCiAgICAvKiBXaGVuICJhbGxvd19zY3JvbGxiYXIiIGlzIEZBTFNFIHN0aWxsIG5lZWQgdG8gcmVtZW1iZXIgdGhlIG5ldwogICAgICogcG9zaXRpb24sIGJ1dCBkb24ndCBhY3R1YWxseSBzY3JvbGwgYnkgc2V0dGluZyAiZG9udF9zY3JvbGwiLiAqLwogICAgZG9udF9zY3JvbGwgPSAhYWxsb3dfc2Nyb2xsYmFyOwogICAgZ3VpX2RyYWdfc2Nyb2xsYmFyKHNiLCB2YWx1ZSwgZHJhZ2dpbmcpOwogICAgZG9udF9zY3JvbGwgPSBkb250X3Njcm9sbF9zYXZlOwp9CgogICAgcGFzY2FsCiAgICB2b2lkCmd1aV9tYWNfc2Nyb2xsX2FjdGlvbihDb250cm9sSGFuZGxlIHRoZUNvbnRyb2wsIHNob3J0IHBhcnRDb2RlKQp7CiAgICAvKiBUT0RPOiBoYXZlIGxpdmUgc3VwcG9ydCAqLwogICAgc2Nyb2xsYmFyX1QgKnNiLCAqc2JfaW5mbzsKICAgIGxvbmcJZGF0YTsKICAgIGxvbmcJdmFsdWU7CiAgICBpbnQJCXBhZ2U7CiAgICBpbnQJCWRyYWdnaW5nID0gRkFMU0U7CiAgICBpbnQJCWRvbnRfc2Nyb2xsX3NhdmUgPSBkb250X3Njcm9sbDsKCiAgICBzYiA9IGd1aV9maW5kX3Njcm9sbGJhcigobG9uZylHZXRDb250cm9sUmVmZXJlbmNlKHRoZUNvbnRyb2wpKTsKCiAgICBpZiAoc2IgPT0gTlVMTCkKCXJldHVybjsKCiAgICBpZiAoc2ItPndwICE9IE5VTEwpCQkvKiBMZWZ0IG9yIHJpZ2h0IHNjcm9sbGJhciAqLwogICAgewoJLyoKCSAqIENhcmVmdWw6IG5lZWQgdG8gZ2V0IHNjcm9sbGJhciBpbmZvIG91dCBvZiBmaXJzdCAobGVmdCkgc2Nyb2xsYmFyCgkgKiBmb3Igd2luZG93LCBidXQga2VlcCByZWFsIHNjcm9sbGJhciB0b28gYmVjYXVzZSB3ZSBtdXN0IHBhc3MgaXQgdG8KCSAqIGd1aV9kcmFnX3Njcm9sbGJhcigpLgoJICovCglzYl9pbmZvID0gJnNiLT53cC0+d19zY3JvbGxiYXJzWzBdOwoKCWlmIChzYl9pbmZvLT5zaXplID4gNSkKCSAgICBwYWdlID0gc2JfaW5mby0+c2l6ZSAtIDI7CS8qIHVzZSB0d28gbGluZXMgb2YgY29udGV4dCAqLwoJZWxzZQoJICAgIHBhZ2UgPSBzYl9pbmZvLT5zaXplOwogICAgfQogICAgZWxzZQkJCS8qIEJvdHRvbSBzY3JvbGxiYXIgKi8KICAgIHsKCXNiX2luZm8gPSBzYjsKCXBhZ2UgPSBXX1dJRFRIKGN1cndpbikgLSA1OwogICAgfQoKICAgIHN3aXRjaCAocGFydENvZGUpCiAgICB7CgljYXNlICBrQ29udHJvbFVwQnV0dG9uUGFydDogICBkYXRhID0gLTE7ICAgIGJyZWFrOwoJY2FzZSAga0NvbnRyb2xEb3duQnV0dG9uUGFydDogZGF0YSA9IDE7ICAgICBicmVhazsKCWNhc2UgIGtDb250cm9sUGFnZURvd25QYXJ0OiAgIGRhdGEgPSBwYWdlOyAgYnJlYWs7CgljYXNlICBrQ29udHJvbFBhZ2VVcFBhcnQ6ICAgICBkYXRhID0gLXBhZ2U7IGJyZWFrOwoJCSAgICBkZWZhdWx0OiBkYXRhID0gMDsgYnJlYWs7CiAgICB9CgogICAgdmFsdWUgPSBzYl9pbmZvLT52YWx1ZSArIGRhdGE7Ci8qICBpZiAodmFsdWUgPiBzYl9pbmZvLT5tYXgpCgl2YWx1ZSA9IHNiX2luZm8tPm1heDsKICAgIGVsc2UgaWYgKHZhbHVlIDwgMCkKCXZhbHVlID0gMDsqLwoKICAgIC8qIFdoZW4gImFsbG93X3Njcm9sbGJhciIgaXMgRkFMU0Ugc3RpbGwgbmVlZCB0byByZW1lbWJlciB0aGUgbmV3CiAgICAgKiBwb3NpdGlvbiwgYnV0IGRvbid0IGFjdHVhbGx5IHNjcm9sbCBieSBzZXR0aW5nICJkb250X3Njcm9sbCIuICovCiAgICBkb250X3Njcm9sbCA9ICFhbGxvd19zY3JvbGxiYXI7CiAgICBndWlfZHJhZ19zY3JvbGxiYXIoc2IsIHZhbHVlLCBkcmFnZ2luZyk7CiAgICBkb250X3Njcm9sbCA9IGRvbnRfc2Nyb2xsX3NhdmU7CgogICAgb3V0X2ZsdXNoKCk7CiAgICBndWlfbWNoX3NldF9zY3JvbGxiYXJfdGh1bWIoc2IsIHZhbHVlLCBzYl9pbmZvLT5zaXplLCBzYl9pbmZvLT5tYXgpOwoKLyogIGlmIChzYl9pbmZvLT53cCAhPSBOVUxMKQogICAgewoJd2luX1QJKndwOwoJaW50CXNiX251bTsKCglzYl9udW0gPSAwOwoJZm9yICh3cCA9IGZpcnN0d2luOyB3cCAhPSBzYi0+d3AgJiYgd3AgIT0gTlVMTDsgd3AgPSBXX05FWFQod3ApKQoJc2JfbnVtKys7CgoJaWYgKHdwICE9IE5VTEwpCgl7CgkgICAgY3VycmVudF9zY3JvbGxiYXIgPSBzYl9udW07CgkgICAgc2Nyb2xsYmFyX3ZhbHVlID0gdmFsdWU7CgkgICAgZ3VpX2RvX3Njcm9sbCgpOwoJICAgIGd1aV9tY2hfc2V0X3Njcm9sbGJhcl90aHVtYihzYiwgdmFsdWUsIHNiX2luZm8tPnNpemUsIHNiX2luZm8tPm1heCk7Cgl9CiAgICB9Ki8KfQoKLyoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIE1hY09TIENsaWNrIEhhbmRsaW5nIHByb2NlZHVyZXMKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKCi8qCiAqIEhhbmRsZSBhIGNsaWNrIGluc2lkZSB0aGUgd2luZG93LCBpdCBtYXkgaGFwcGVucyBpbiB0aGUKICogc2Nyb2xsYmFyIG9yIHRoZSBjb250ZW50cy4KICoKICogVE9ETzogQWRkIHN1cHBvcnQgZm9yIHBvdGVudGlhbCBUT09MQkFSCiAqLwogICAgdm9pZApndWlfbWFjX2RvSW5Db250ZW50Q2xpY2soRXZlbnRSZWNvcmQgKnRoZUV2ZW50LCBXaW5kb3dQdHIgd2hpY2hXaW5kb3cpCnsKICAgIFBvaW50CQl0aGVQb2ludDsKICAgIGludF91CQl2aW1Nb2RpZmllcnM7CiAgICBzaG9ydAkJdGhlUG9ydGlvbjsKICAgIENvbnRyb2xIYW5kbGUJdGhlQ29udHJvbDsKICAgIGludAkJCXZpbU1vdXNlQnV0dG9uOwogICAgc2hvcnQJCWRibENsaWNrOwoKICAgIHRoZVBvaW50ID0gdGhlRXZlbnQtPndoZXJlOwogICAgR2xvYmFsVG9Mb2NhbCgmdGhlUG9pbnQpOwogICAgU2VsZWN0V2luZG93KHdoaWNoV2luZG93KTsKCiAgICB0aGVQb3J0aW9uID0gRmluZENvbnRyb2wodGhlUG9pbnQsIHdoaWNoV2luZG93LCAmdGhlQ29udHJvbCk7CgogICAgaWYgKHRoZUNvbnRyb2wgIT0gTlVMKQogICAgewoJLyogV2UgaGl0IGEgc2NvbGxiYXIgKi8KCglpZiAodGhlUG9ydGlvbiAhPSBrQ29udHJvbEluZGljYXRvclBhcnQpCgl7CgkgICAgZHJhZ2dlZF9zYiA9IHRoZUNvbnRyb2w7CgkgICAgVHJhY2tDb250cm9sKHRoZUNvbnRyb2wsIHRoZVBvaW50LCBnU2Nyb2xsQWN0aW9uKTsKCSAgICBkcmFnZ2VkX3NiID0gTlVMTDsKCX0KCWVsc2UKCXsKCSAgICBkcmFnZ2VkX3NiID0gdGhlQ29udHJvbDsKI2lmIDEKCSAgICBUcmFja0NvbnRyb2wodGhlQ29udHJvbCwgdGhlUG9pbnQsIGdTY3JvbGxEcmFnKTsKI2Vsc2UKCSAgICBUcmFja0NvbnRyb2wodGhlQ29udHJvbCwgdGhlUG9pbnQsIE5VTEwpOwojZW5kaWYKCSAgICAvKiBwYXNzIDAgYXMgdGhlIHBhcnQgdG8gdGVsbCBndWlfbWFjX2RyYWdfdGh1bWIsIHRoYXQgdGhlIG1vdXNlCgkgICAgICogYnV0dG9uIGhhcyBiZWVuIHJlbGVhc2VkICovCgkgICAgZ3VpX21hY19kcmFnX3RodW1iKHRoZUNvbnRyb2wsIDApOyAvKiBTaG91bGQgaXQgYmUgdGhlUG9ydGlvbiA/IChEYW55KSAqLwoJICAgIGRyYWdnZWRfc2IgPSBOVUxMOwoJfQogICAgfQogICAgZWxzZQogICAgewoJLyogV2UgYXJlIGluc2lkZSB0aGUgY29udGVudHMgKi8KCgkvKiBDb252ZXJ0IHRoZSBDVFJMLCBPUFRJT04sIFNISUZUIGFuZCBDTUQga2V5ICovCgl2aW1Nb2RpZmllcnMgPSBFdmVudE1vZGlmaWVyczJWaW1Nb3VzZU1vZGlmaWVycyh0aGVFdmVudC0+bW9kaWZpZXJzKTsKCgkvKiBEZWZhdWx0cyB0byBNT1VTRV9MRUZUIGFzIHRoZXJlJ3Mgb25seSBvbmUgbW91c2UgYnV0dG9uICovCgl2aW1Nb3VzZUJ1dHRvbiA9IE1PVVNFX0xFRlQ7CgoJLyogQ29udmVydCB0aGUgQ1RSTF9NT1VTRV9MRUZUIHRvIE1PVVNFX1JJR0hUICovCgkvKiBUT0RPOiBORUVERUQ/ICovCgljbGlja0lzUG9wdXAgPSBGQUxTRTsKCglpZiAoKGd1aS5NYWNPU0hhdmVDbnR4TWVudSkgJiYgKG1vdXNlX21vZGVsX3BvcHVwKCkpKQoJICAgIGlmIChJc1Nob3dDb250ZXh0dWFsTWVudUNsaWNrKHRoZUV2ZW50KSkKCSAgICB7CgkJdmltTW91c2VCdXR0b24gPSBNT1VTRV9SSUdIVDsKCQl2aW1Nb2RpZmllcnMgJj0gfk1PVVNFX0NUUkw7CgkJY2xpY2tJc1BvcHVwID0gVFJVRTsKCSAgICB9CgoJLyogSXMgaXQgYSBkb3VibGUgY2xpY2sgPyAqLwoJZGJsQ2xpY2sgPSAoKHRoZUV2ZW50LT53aGVuIC0gbGFzdE1vdXNlVGljaykgPCBHZXREYmxUaW1lKCkpOwoKCS8qIFNlbmQgdGhlIG1vdXNlIGNsaWNrIHRvIFZpbSAqLwoJZ3VpX3NlbmRfbW91c2VfZXZlbnQodmltTW91c2VCdXR0b24sIHRoZVBvaW50LmgsCgkJCQkJICB0aGVQb2ludC52LCBkYmxDbGljaywgdmltTW9kaWZpZXJzKTsKCgkvKiBDcmVhdGUgdGhlIHJlY3RhbmdsZSBhcm91bmQgdGhlIGN1cnNvciB0byBkZXRlY3QKCSAqIHRoZSBtb3VzZSBkcmFnZ2luZwoJICovCiNpZiAwCgkvKiBUT0RPOiBEbyB3ZSBuZWVkIHRvIHRoaXMgZXZlbiBmb3IgdGhlIGNvbnRleHR1YWwgbWVudT8KCSAqIEl0IG1heSBiZSByZXF1aXJlIGZvciBwb3B1cF9zZXRwb3MsIGJ1dCBmb3IgcG9wdXA/CgkgKi8KCWlmICh2aW1Nb3VzZUJ1dHRvbiA9PSBNT1VTRV9MRUZUKQojZW5kaWYKCXsKCSAgICBTZXRSZWN0KCZkcmFnUmVjdCwgRklMTF9YKFhfMl9DT0wodGhlUG9pbnQuaCkpLAoJCQkJRklMTF9ZKFlfMl9ST1codGhlUG9pbnQudikpLAoJCQkJRklMTF9YKFhfMl9DT0wodGhlUG9pbnQuaCkrMSksCgkJCQlGSUxMX1koWV8yX1JPVyh0aGVQb2ludC52KSsxKSk7CgoJICAgIGRyYWdSZWN0RW5ibCA9IFRSVUU7CgkgICAgZHJhZ1JlY3RDb250cm9sID0ga0NyZWF0ZVJlY3Q7Cgl9CiAgICB9Cn0KCi8qCiAqIEhhbmRsZSB0aGUgY2xpY2sgaW4gdGhlIHRpdGxlYmFyICh0byBtb3ZlIHRoZSB3aW5kb3cpCiAqLwogICAgdm9pZApndWlfbWFjX2RvSW5EcmFnQ2xpY2soUG9pbnQgd2hlcmUsIFdpbmRvd1B0ciB3aGljaFdpbmRvdykKewogICAgUmVjdAltb3ZpbmdMaW1pdHM7CiAgICBSZWN0CSptb3ZpbmdMaW1pdHNQdHIgPSAmbW92aW5nTGltaXRzOwoKICAgIC8qIFRPRE86IG1heSB0cnkgdG8gcHJldmVudCBtb3ZlIG91dHNpZGUgc2NyZWVuPyAqLwogICAgbW92aW5nTGltaXRzUHRyID0gR2V0UmVnaW9uQm91bmRzKEdldEdyYXlSZ24oKSwgJm1vdmluZ0xpbWl0cyk7CiAgICBEcmFnV2luZG93KHdoaWNoV2luZG93LCB3aGVyZSwgbW92aW5nTGltaXRzUHRyKTsKfQoKLyoKICogSGFuZGxlIHRoZSBjbGljayBpbiB0aGUgZ3JvdyBib3gKICovCiAgICB2b2lkCmd1aV9tYWNfZG9Jbkdyb3dDbGljayhQb2ludCB3aGVyZSwgV2luZG93UHRyIHdoaWNoV2luZG93KQp7CgogICAgbG9uZwkgICAgbmV3U2l6ZTsKICAgIHVuc2lnbmVkIHNob3J0ICBuZXdXaWR0aDsKICAgIHVuc2lnbmVkIHNob3J0ICBuZXdIZWlnaHQ7CiAgICBSZWN0CSAgICByZXNpemVMaW1pdHM7CiAgICBSZWN0CSAgICAqcmVzaXplTGltaXRzUHRyID0gJnJlc2l6ZUxpbWl0czsKICAgIFJlY3QJICAgIE5ld0NvbnRlbnRSZWN0OwoKICAgIHJlc2l6ZUxpbWl0c1B0ciA9IEdldFJlZ2lvbkJvdW5kcyhHZXRHcmF5UmduKCksICZyZXNpemVMaW1pdHMpOwoKICAgIC8qIFNldCB0aGUgbWluaW11biBzaXplICovCiAgICAvKiBUT0RPOiBTaG91bGQgdGhpcyBjb21lIGZyb20gVmltPyAqLwogICAgcmVzaXplTGltaXRzLnRvcCA9IDEwMDsKICAgIHJlc2l6ZUxpbWl0cy5sZWZ0ID0gMTAwOwoKICAgIG5ld1NpemUgPSBSZXNpemVXaW5kb3cod2hpY2hXaW5kb3csIHdoZXJlLCAmcmVzaXplTGltaXRzLCAmTmV3Q29udGVudFJlY3QpOwogICAgbmV3V2lkdGggID0gTmV3Q29udGVudFJlY3QucmlnaHQgLSBOZXdDb250ZW50UmVjdC5sZWZ0OwogICAgbmV3SGVpZ2h0ID0gTmV3Q29udGVudFJlY3QuYm90dG9tIC0gTmV3Q29udGVudFJlY3QudG9wOwogICAgZ3VpX3Jlc2l6ZV9zaGVsbChuZXdXaWR0aCwgbmV3SGVpZ2h0KTsKICAgIGd1aV9tY2hfc2V0X2JnX2NvbG9yKGd1aS5iYWNrX3BpeGVsKTsKICAgIGd1aV9zZXRfc2hlbGxzaXplKFRSVUUsIEZBTFNFLCBSRVNJWkVfQk9USCk7Cn0KCi8qCiAqIEhhbmRsZSB0aGUgY2xpY2sgaW4gdGhlIHpvb20gYm94CiAqLwogICAgc3RhdGljIHZvaWQKZ3VpX21hY19kb0luWm9vbUNsaWNrKEV2ZW50UmVjb3JkICp0aGVFdmVudCwgV2luZG93UHRyIHdoaWNoV2luZG93KQp7CiAgICBSZWN0CXI7CiAgICBQb2ludAlwOwogICAgc2hvcnQJdGhlUGFydDsKCiAgICAvKiBpZGVhbCB3aWR0aCBpcyBjdXJyZW50ICovCiAgICBwLmggPSBDb2x1bW5zICogZ3VpLmNoYXJfd2lkdGggKyAyICogZ3VpLmJvcmRlcl9vZmZzZXQ7CiAgICBpZiAoZ3VpLndoaWNoX3Njcm9sbGJhcnNbU0JBUl9MRUZUXSkKCXAuaCArPSBndWkuc2Nyb2xsYmFyX3dpZHRoOwogICAgaWYgKGd1aS53aGljaF9zY3JvbGxiYXJzW1NCQVJfUklHSFRdKQoJcC5oICs9IGd1aS5zY3JvbGxiYXJfd2lkdGg7CiAgICAvKiBpZGVhbCBoZWlnaHQgaXMgYXMgaGVpZ2ggYXMgd2UgY2FuIGdldCAqLwogICAgcC52ID0gMTUgKiAxMDI0OwoKICAgIHRoZVBhcnQgPSBJc1dpbmRvd0luU3RhbmRhcmRTdGF0ZSh3aGljaFdpbmRvdywgJnAsICZyKQoJCQkJCQkgICAgICAgPyBpblpvb21JbiA6IGluWm9vbU91dDsKCiAgICBpZiAoIVRyYWNrQm94KHdoaWNoV2luZG93LCB0aGVFdmVudC0+d2hlcmUsIHRoZVBhcnQpKQoJcmV0dXJuOwoKICAgIC8qIHVzZSByZXR1cm5lZCB3aWR0aCAqLwogICAgcC5oID0gci5yaWdodCAtIHIubGVmdDsKICAgIC8qIGFkanVzdCByZXR1cm5lZCBoZWlnaHQgKi8KICAgIHAudiA9IHIuYm90dG9tIC0gci50b3AgLSAyICogZ3VpLmJvcmRlcl9vZmZzZXQ7CiAgICBpZiAoZ3VpLndoaWNoX3Njcm9sbGJhcnNbU0JBUl9CT1RUT01dKQoJcC52IC09IGd1aS5zY3JvbGxiYXJfaGVpZ2h0OwogICAgcC52IC09IHAudiAlIGd1aS5jaGFyX2hlaWdodDsKICAgIHAudiArPSAyICogZ3VpLmJvcmRlcl93aWR0aDsKICAgIGlmIChndWkud2hpY2hfc2Nyb2xsYmFyc1tTQkFSX0JPVFRPTV0pOwoJcC52ICs9IGd1aS5zY3JvbGxiYXJfaGVpZ2h0OwoKICAgIFpvb21XaW5kb3dJZGVhbCh3aGljaFdpbmRvdywgdGhlUGFydCwgJnApOwoKICAgIEdldFdpbmRvd0JvdW5kcyh3aGljaFdpbmRvdywga1dpbmRvd0NvbnRlbnRSZ24sICZyKTsKICAgIGd1aV9yZXNpemVfc2hlbGwoci5yaWdodCAtIHIubGVmdCwgci5ib3R0b20gLSByLnRvcCk7CiAgICBndWlfbWNoX3NldF9iZ19jb2xvcihndWkuYmFja19waXhlbCk7CiAgICBndWlfc2V0X3NoZWxsc2l6ZShUUlVFLCBGQUxTRSwgUkVTSVpFX0JPVEgpOwp9CgovKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogTWFjT1MgRXZlbnQgSGFuZGxpbmcgcHJvY2VkdXJlCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCi8qCiAqIEhhbmRsZSB0aGUgVXBkYXRlIEV2ZW50CiAqLwoKICAgIHZvaWQKZ3VpX21hY19kb1VwZGF0ZUV2ZW50KEV2ZW50UmVjb3JkICpldmVudCkKewogICAgV2luZG93UHRyCXdoaWNoV2luZG93OwogICAgR3JhZlB0cglzYXZlUG9ydDsKICAgIFJnbkhhbmRsZQl1cGRhdGVSZ247CiAgICBSZWN0CXVwZGF0ZVJlY3Q7CiAgICBSZWN0CSp1cGRhdGVSZWN0UHRyOwogICAgUmVjdAlyYzsKICAgIFJlY3QJZ3Jvd1JlY3Q7CiAgICBSZ25IYW5kbGUJc2F2ZVJnbjsKCgogICAgdXBkYXRlUmduID0gTmV3UmduKCk7CiAgICBpZiAodXBkYXRlUmduID09IE5VTEwpCglyZXR1cm47CgogICAgLyogVGhpcyBjb3VsZCBiZSBkb25lIGJ5IHRoZSBjYWxsZXIgYXMgd2UKICAgICAqIGRvbid0IHJlcXVpcmUgYW55dGhpbmcgZWxzZSBvdXQgb2YgdGhlIGV2ZW50CiAgICAgKi8KICAgIHdoaWNoV2luZG93ID0gKFdpbmRvd1B0cikgZXZlbnQtPm1lc3NhZ2U7CgogICAgLyogU2F2ZSBDdXJyZW50IFBvcnQgKi8KICAgIEdldFBvcnQoJnNhdmVQb3J0KTsKCiAgICAvKiBTZWxlY3QgdGhlIFdpbmRvdydzIFBvcnQgKi8KICAgIFNldFBvcnRXaW5kb3dQb3J0KHdoaWNoV2luZG93KTsKCiAgICAvKiBMZXQncyB1cGRhdGUgdGhlIHdpbmRvdyAqLwogICAgICBCZWdpblVwZGF0ZSh3aGljaFdpbmRvdyk7CgkvKiBSZWRyYXcgdGhlIGJpZ2dlc3QgcmVjdGFuZ2xlIGNvdmVyaW5nIHRoZSBhcmVhCgkgKiB0byBiZSB1cGRhdGVkLgoJICovCglHZXRQb3J0VmlzaWJsZVJlZ2lvbihHZXRXaW5kb3dQb3J0KHdoaWNoV2luZG93KSwgdXBkYXRlUmduKTsKIyBpZiAwCgkvKiBXb3VsZCBiZSBtb3JlIGFwcHJvcHJpYXRlIHRvIHVzZSB0aGUgZm9sbHdpbmcgYnV0IGRvZXNuJ3QKCSAqIHNlZW0gdG8gd29yayB1bmRlciBNYWNPUyBYIChEYW55KQoJICovCglHZXRXaW5kb3dSZWdpb24od2hpY2hXaW5kb3csIGtXaW5kb3dVcGRhdGVSZ24sIHVwZGF0ZVJnbik7CiMgZW5kaWYKCgkvKiBVc2UgdGhlIEhMb2NrIHVzZWxlc3MgaW4gQ2FyYm9uPyBJcyBpdCBoYXJtZnVsPyovCglITG9jaygoSGFuZGxlKSB1cGRhdGVSZ24pOwoKCSAgdXBkYXRlUmVjdFB0ciA9IEdldFJlZ2lvbkJvdW5kcyh1cGRhdGVSZ24sICZ1cGRhdGVSZWN0KTsKIyBpZiAwCgkgIC8qIENvZGUgZnJvbSBvcmlnaW5hbCBDYXJib24gUG9ydCAodXNpbmcgR2V0V2luZG93UmVnaW9uLgoJICAgKiBJIGJlbGlldmUgdGhlIFVwZGF0ZVJnbiBpcyBhbHJlYWR5IGluIGxvY2FsIChEYW55KQoJICAgKi8KCSAgR2xvYmFsVG9Mb2NhbCgmdG9wTGVmdCh1cGRhdGVSZWN0KSk7IC8qIHByZUNhcmJvbj8gKi8KCSAgR2xvYmFsVG9Mb2NhbCgmYm90UmlnaHQodXBkYXRlUmVjdCkpOwojIGVuZGlmCgkgIC8qIFVwZGF0ZSB0aGUgY29udGVudCAoaS5lLiB0aGUgdGV4dCkgKi8KCSAgZ3VpX3JlZHJhdyh1cGRhdGVSZWN0UHRyLT5sZWZ0LCB1cGRhdGVSZWN0UHRyLT50b3AsCgkJICAgICAgdXBkYXRlUmVjdFB0ci0+cmlnaHQgLSB1cGRhdGVSZWN0UHRyLT5sZWZ0LAoJCSAgICAgIHVwZGF0ZVJlY3RQdHItPmJvdHRvbSAgIC0gdXBkYXRlUmVjdFB0ci0+dG9wKTsKCSAgLyogQ2xlYXIgdGhlIGJvcmRlciBhcmVhcyBpZiBuZWVkZWQgKi8KCSAgZ3VpX21jaF9zZXRfYmdfY29sb3IoZ3VpLmJhY2tfcGl4ZWwpOwoJICBpZiAodXBkYXRlUmVjdFB0ci0+bGVmdCA8IEZJTExfWCgwKSkKCSAgewoJICAgIFNldFJlY3QoJnJjLCAwLCAwLCBGSUxMX1goMCksIEZJTExfWShSb3dzKSk7CgkgICAgRXJhc2VSZWN0KCZyYyk7CgkgIH0KCSAgaWYgKHVwZGF0ZVJlY3RQdHItPnRvcCA8IEZJTExfWSgwKSkKCSAgewoJICAgIFNldFJlY3QoJnJjLCAwLCAwLCBGSUxMX1goQ29sdW1ucyksIEZJTExfWSgwKSk7CgkgICAgRXJhc2VSZWN0KCZyYyk7CgkgIH0KCSAgaWYgKHVwZGF0ZVJlY3RQdHItPnJpZ2h0ID4gRklMTF9YKENvbHVtbnMpKQoJICB7CgkgICAgU2V0UmVjdCgmcmMsIEZJTExfWChDb2x1bW5zKSwgMCwKCQkJICAgRklMTF9YKENvbHVtbnMpICsgZ3VpLmJvcmRlcl9vZmZzZXQsIEZJTExfWShSb3dzKSk7CgkgICAgRXJhc2VSZWN0KCZyYyk7CgkgIH0KCSAgaWYgKHVwZGF0ZVJlY3RQdHItPmJvdHRvbSA+IEZJTExfWShSb3dzKSkKCSAgewoJICAgIFNldFJlY3QoJnJjLCAwLCBGSUxMX1koUm93cyksIEZJTExfWChDb2x1bW5zKSArIGd1aS5ib3JkZXJfb2Zmc2V0LAoJCQkJCSAgICBGSUxMX1koUm93cykgKyBndWkuYm9yZGVyX29mZnNldCk7CgkgICAgRXJhc2VSZWN0KCZyYyk7CgkgIH0KCUhVbmxvY2soKEhhbmRsZSkgdXBkYXRlUmduKTsKCURpc3Bvc2VSZ24odXBkYXRlUmduKTsKCgkvKiBVcGRhdGUgc2Nyb2xsYmFycyAqLwoJRHJhd0NvbnRyb2xzKHdoaWNoV2luZG93KTsKCgkvKiBVcGRhdGUgdGhlIEdyb3dCb3ggKi8KCS8qIFRha2VuIGZyb20gRkFRIDMzLTI3ICovCglzYXZlUmduID0gTmV3UmduKCk7CglHZXRXaW5kb3dCb3VuZHMod2hpY2hXaW5kb3csIGtXaW5kb3dHcm93UmduLCAmZ3Jvd1JlY3QpOwoJR2V0Q2xpcChzYXZlUmduKTsKCUNsaXBSZWN0KCZncm93UmVjdCk7CglEcmF3R3Jvd0ljb24od2hpY2hXaW5kb3cpOwoJU2V0Q2xpcChzYXZlUmduKTsKCURpc3Bvc2VSZ24oc2F2ZVJnbik7CiAgICAgIEVuZFVwZGF0ZSh3aGljaFdpbmRvdyk7CgogICAgLyogUmVzdG9yZSBvcmlnaW5hbCBQb3J0ICovCiAgICBTZXRQb3J0KHNhdmVQb3J0KTsKfQoKLyoKICogSGFuZGxlIHRoZSBhY3RpdmF0ZS9kZWFjdGl2YXRlIGV2ZW50CiAqIChhcHBseSB0byBhIHdpbmRvdykKICovCiAgICB2b2lkCmd1aV9tYWNfZG9BY3RpdmF0ZUV2ZW50KEV2ZW50UmVjb3JkICpldmVudCkKewogICAgV2luZG93UHRyCXdoaWNoV2luZG93OwoKICAgIHdoaWNoV2luZG93ID0gKFdpbmRvd1B0cikgZXZlbnQtPm1lc3NhZ2U7CiAgICBpZiAoKGV2ZW50LT5tb2RpZmllcnMpICYgYWN0aXZlRmxhZykKCS8qIEFjdGl2YXRlICovCglndWlfZm9jdXNfY2hhbmdlKFRSVUUpOwogICAgZWxzZQogICAgewoJLyogRGVhY3RpdmF0ZSAqLwoJZ3VpX2ZvY3VzX2NoYW5nZShGQUxTRSk7Ci8qCURPTidUIEtOT1cgd2hhdCB0aGUgY29kZSBiZWxvdyB3YXMgZG9pbmcKCWZvdW5kIGluIHRoZSBkZWFjdGl2YXRlIGNsYXVzZSwgYnV0IHRoZQoJY2xhdXNlIHdyaXR0aW5nIFRSVUUgaW50byBpbl9mb2N1cyAoQlVHKQogKi8KCiNpZiAwCS8qIFJlbW92ZWQgYnkgRGFueSBhcyBwZXIgYWJvdmUgSnVuZSAyMDAxICovCglhX2Jvb2wgPSBmYWxzZTsKCVNldFByZXNlcnZlR2x5cGgoYV9ib29sKTsKCVNldE91dGxpbmVQcmVmZXJyZWQoYV9ib29sKTsKI2VuZGlmCiAgICB9Cn0KCgovKgogKiBIYW5kbGUgdGhlIHN1c3BlbmQvcmVzdW1lIGV2ZW50CiAqIChhcHBseSB0byB0aGUgYXBwbGljYXRpb24pCiAqLwogICAgdm9pZApndWlfbWFjX2RvU3VzcGVuZEV2ZW50KEV2ZW50UmVjb3JkICpldmVudCkKewogICAgLyogVGhlIGZyb250bW9zdCBhcHBsaWNhdGlvbiBqdXN0IGNoYW5nZWQgKi8KCiAgICAvKiBOT1RFOiB0aGUgc3VzcGVuZCBtYXkgaGFwcGVuIGJlZm9yZSB0aGUgZGVhY3RpdmF0ZQogICAgICogICAgICAgc2VlbiBvbiBNYWNPUyBYCiAgICAgKi8KCiAgICAvKiBNYXkgbm90IG5lZWQgdG8gY2hhbmdlIGZvY3VzIGFzIHRoZSB3aW5kb3cgd2lsbAogICAgICogZ2V0IGFuIGFjdGl2YXRlL2Rlc2FjdGl2YXRlIGV2ZW50CiAgICAgKi8KICAgIGlmIChldmVudC0+bWVzc2FnZSAmIDEpCgkvKiBSZXN1bWUgKi8KCWd1aV9mb2N1c19jaGFuZ2UoVFJVRSk7CiAgICBlbHNlCgkvKiBTdXNwZW5kICovCglndWlfZm9jdXNfY2hhbmdlKEZBTFNFKTsKfQoKLyoKICogSGFuZGxlIHRoZSBrZXkKICovCiNpZmRlZiBVU0VfQ0FSQk9OS0VZSEFORExFUgoKc3RhdGljIGludCBkaWFsb2dfYnVzeSA9IEZBTFNFOwkgICAgLyogVFJVRSB3aGVuIGd1aV9tY2hfZGlhbG9nKCkgd2FudHMgdGhlIGtleXMgKi8KCiMgZGVmaW5lIElOTElORV9LRVlfQlVGRkVSX1NJWkUgODAKICAgIHN0YXRpYyBwYXNjYWwgT1NTdGF0dXMKZ3VpX21hY19kb0tleUV2ZW50Q2FyYm9uKAoJRXZlbnRIYW5kbGVyQ2FsbFJlZiBuZXh0SGFuZGxlciwKCUV2ZW50UmVmIHRoZUV2ZW50LAoJdm9pZCAqZGF0YSkKewogICAgLyogTXVsdGlieXRlLWZyaWVuZGx5IGtleSBldmVudCBoYW5kbGVyICovCiAgICBPU1N0YXR1cwllID0gLTE7CiAgICBVSW50MzIJYWN0dWFsU2l6ZTsKICAgIFVuaUNoYXIJKnRleHQ7CiAgICBjaGFyX3UJcmVzdWx0W0lOTElORV9LRVlfQlVGRkVSX1NJWkVdOwogICAgc2hvcnQJbGVuID0gMDsKICAgIFVJbnQzMglrZXlfc3ltOwogICAgY2hhcgljaGFyY29kZTsKICAgIGludAkJa2V5X2NoYXI7CiAgICBVSW50MzIJbW9kaWZpZXJzOwogICAgc2l6ZV90CWVuY0xlbjsKICAgIGNoYXJfdQkqdG8gPSBOVUxMOwogICAgQm9vbGVhbglpc1NwZWNpYWwgPSBGQUxTRTsKICAgIGludAkJaTsKCiAgICAvKiBNYXNrIHRoZSBtb3VzZSAoYXMgcGVyIHVzZXIgc2V0dGluZykgKi8KICAgIGlmIChwX21oKQoJT2JzY3VyZUN1cnNvcigpOwoKICAgIGRvCiAgICB7CgkvKiBEb24ndCB1c2UgdGhlIGtleXMgd2hlbiB0aGUgZGlhbG9nIHdhbnRzIHRoZW0uICovCglpZiAoZGlhbG9nX2J1c3kpCgkgICAgYnJlYWs7CgoJaWYgKG5vRXJyICE9IEdldEV2ZW50UGFyYW1ldGVyKHRoZUV2ZW50LCBrRXZlbnRQYXJhbVRleHRJbnB1dFNlbmRUZXh0LAoJCSAgICB0eXBlVW5pY29kZVRleHQsIE5VTEwsIDAsICZhY3R1YWxTaXplLCBOVUxMKSkKCSAgICBicmVhazsKCgl0ZXh0ID0gKFVuaUNoYXIgKilhbGxvYyhhY3R1YWxTaXplKTsKCglpZiAodGV4dCkKCXsKCSAgICBkbwoJICAgIHsKCQlpZiAobm9FcnIgIT0gR2V0RXZlbnRQYXJhbWV0ZXIodGhlRXZlbnQsCgkJCSAgICBrRXZlbnRQYXJhbVRleHRJbnB1dFNlbmRUZXh0LAoJCQkgICAgdHlwZVVuaWNvZGVUZXh0LCBOVUxMLCBhY3R1YWxTaXplLCBOVUxMLCB0ZXh0KSkKCQkgICAgYnJlYWs7CgkJRXZlbnRSZWYga2V5RXZlbnQ7CgkJaWYgKG5vRXJyICE9IEdldEV2ZW50UGFyYW1ldGVyKHRoZUV2ZW50LAoJCQkgICAga0V2ZW50UGFyYW1UZXh0SW5wdXRTZW5kS2V5Ym9hcmRFdmVudCwKCQkJICAgIHR5cGVFdmVudFJlZiwgTlVMTCwgc2l6ZW9mKEV2ZW50UmVmKSwgTlVMTCwgJmtleUV2ZW50KSkKCQkgICAgYnJlYWs7CgkJaWYgKG5vRXJyICE9IEdldEV2ZW50UGFyYW1ldGVyKGtleUV2ZW50LAoJCQkgICAga0V2ZW50UGFyYW1LZXlNb2RpZmllcnMsCgkJCSAgICB0eXBlVUludDMyLCBOVUxMLCBzaXplb2YoVUludDMyKSwgTlVMTCwgJm1vZGlmaWVycykpCgkJICAgIGJyZWFrOwoJCWlmIChub0VyciAhPSBHZXRFdmVudFBhcmFtZXRlcihrZXlFdmVudCwKCQkJICAgIGtFdmVudFBhcmFtS2V5Q29kZSwKCQkJICAgIHR5cGVVSW50MzIsIE5VTEwsIHNpemVvZihVSW50MzIpLCBOVUxMLCAma2V5X3N5bSkpCgkJICAgIGJyZWFrOwoJCWlmIChub0VyciAhPSBHZXRFdmVudFBhcmFtZXRlcihrZXlFdmVudCwKCQkJICAgIGtFdmVudFBhcmFtS2V5TWFjQ2hhckNvZGVzLAoJCQkgICAgdHlwZUNoYXIsIE5VTEwsIHNpemVvZihjaGFyKSwgTlVMTCwgJmNoYXJjb2RlKSkKCQkgICAgYnJlYWs7CgoJCWtleV9jaGFyID0gY2hhcmNvZGU7CgoJCWlmIChtb2RpZmllcnMgJiBjb250cm9sS2V5KQoJCXsKCQkgICAgaWYgKChtb2RpZmllcnMgJiB+KGNvbnRyb2xLZXl8c2hpZnRLZXkpKSA9PSAwCgkJCSAgICAmJiAoa2V5X2NoYXIgPT0gJzInIHx8IGtleV9jaGFyID09ICc2JykpCgkJICAgIHsKCQkJLyogQ1RSTC1eIGFuZCBDVFJMLUAgZG9uJ3Qgd29yayBpbiB0aGUgbm9ybWFsIHdheS4gKi8KCQkJaWYgKGtleV9jaGFyID09ICcyJykKCQkJICAgIGtleV9jaGFyID0gQ3RybF9BVDsKCQkJZWxzZQoJCQkgICAga2V5X2NoYXIgPSBDdHJsX0hBVDsKCgkJCXRleHRbMF0gPSAoVW5pQ2hhcilrZXlfY2hhcjsKCQkJbW9kaWZpZXJzID0gMDsKCQkgICAgfQoJCX0KCgkJaWYgKG1vZGlmaWVycyAmIGNtZEtleSkKI2lmbmRlZiBVU0VfQ01EX0tFWQoJCSAgICBicmVhazsgIC8qIExldCBzeXN0ZW0gaGFuZGxlIENtZCsuLi4gKi8KI2Vsc2UKCQl7CgkJICAgIC8qIEludGVyY2VwdCBDTUQtLiAqLwoJCSAgICBpZiAoa2V5X2NoYXIgPT0gJy4nKQoJCQlnb3RfaW50ID0gVFJVRTsKCgkJICAgIC8qIENvbnZlcnQgdGhlIG1vZGlmaWVycyAqLwoJCSAgICBtb2RpZmllcnMgPSBFdmVudE1vZGlmaWVyczJWaW1Nb2RpZmllcnMobW9kaWZpZXJzKTsKCgkJICAgIC8qIEZvbGxvd2luZyBjb2RlIHRvIHNpbXBsaWZ5IGFuZCBjb25zb2xpZGF0ZSBtb2RpZmllcnMKCQkgICAgICogdGFrZW4gbGliZXJhbGx5IGZyb20gZ3VpX3c0OC5jICovCgoJCSAgICBrZXlfY2hhciA9IHNpbXBsaWZ5X2tleShrZXlfY2hhciwgKGludCAqKSZtb2RpZmllcnMpOwoKCQkgICAgLyogcmVtb3ZlIFNISUZUIGZvciBrZXlzIHRoYXQgYXJlIGFscmVhZHkgc2hpZnRlZCwgZS5nLiwKCQkgICAgICogJygnIGFuZCAnKicgKi8KCQkgICAgaWYgKGtleV9jaGFyIDwgMHgxMDAgJiYKCQkJICAgICFpc2FscGhhKGtleV9jaGFyKSAmJiBpc3ByaW50KGtleV9jaGFyKSkKCQkJbW9kaWZpZXJzICY9IH5NT0RfTUFTS19TSElGVDsKCgkJICAgIC8qIEludGVycHJldCBNRVRBLCBpbmNsdWRlIFNISUZULCBldGMuICovCgkJICAgIGtleV9jaGFyID0gZXh0cmFjdF9tb2RpZmllcnMoa2V5X2NoYXIsIChpbnQgKikmbW9kaWZpZXJzKTsKCQkgICAgaWYgKGtleV9jaGFyID09IENTSSkKCQkJa2V5X2NoYXIgPSBLX0NTSTsKCgkJICAgIGlmIChtb2RpZmllcnMpCgkJICAgIHsKCQkJcmVzdWx0W2xlbisrXSA9IENTSTsKCQkJcmVzdWx0W2xlbisrXSA9IEtTX01PRElGSUVSOwoJCQlyZXN1bHRbbGVuKytdID0gbW9kaWZpZXJzOwoJCSAgICB9CgoJCSAgICBpc1NwZWNpYWwgPSBUUlVFOwoJCX0KI2VuZGlmCgkJZWxzZQoJCXsKCQkgICAgLyogRmluZCB0aGUgc3BlY2lhbCBrZXkgKGVnLiwgZm9yIGN1cnNvciBrZXlzKSAqLwoJCSAgICBpZiAoIShhY3R1YWxTaXplID4gc2l6ZW9mKFVuaUNoYXIpKSAmJgoJCQkgICAgKCh0ZXh0WzBdIDwgMHgyMCkgfHwgKHRleHRbMF0gPT0gMHg3ZikpKQoJCSAgICB7CgkJCWZvciAoaSA9IDA7IHNwZWNpYWxfa2V5c1tpXS5rZXlfc3ltICE9IChLZXlTeW0pMDsgKytpKQoJCQkgICAgaWYgKHNwZWNpYWxfa2V5c1tpXS5rZXlfc3ltID09IGtleV9zeW0pCgkJCSAgICB7CgkJCQlrZXlfY2hhciA9IFRPX1NQRUNJQUwoc3BlY2lhbF9rZXlzW2ldLnZpbV9jb2RlMCwKCQkJCQlzcGVjaWFsX2tleXNbaV0udmltX2NvZGUxKTsKCQkJCWtleV9jaGFyID0gc2ltcGxpZnlfa2V5KGtleV9jaGFyLAoJCQkJCShpbnQgKikmbW9kaWZpZXJzKTsKCQkJCWlzU3BlY2lhbCA9IFRSVUU7CgkJCQlicmVhazsKCQkJICAgIH0KCQkgICAgfQoJCX0KCgkJaWYgKGlzU3BlY2lhbCAmJiBJU19TUEVDSUFMKGtleV9jaGFyKSkKCQl7CgkJICAgIHJlc3VsdFtsZW4rK10gPSBDU0k7CgkJICAgIHJlc3VsdFtsZW4rK10gPSBLX1NFQ09ORChrZXlfY2hhcik7CgkJICAgIHJlc3VsdFtsZW4rK10gPSBLX1RISVJEKGtleV9jaGFyKTsKCQl9CgkJZWxzZQoJCXsKCQkgICAgZW5jTGVuID0gYWN0dWFsU2l6ZTsKCQkgICAgdG8gPSBtYWNfdXRmMTZfdG9fZW5jKHRleHQsIGFjdHVhbFNpemUsICZlbmNMZW4pOwoJCX0KCgkJaWYgKHRvKQoJCXsKCQkgICAgLyogVGhpcyBpcyBiYXNpY2FsbHkgYWRkX3RvX2lucHV0X2J1Zl9jc2koKSAqLwoJCSAgICBmb3IgKGkgPSAwOyBpIDwgZW5jTGVuICYmIGxlbiA8IChJTkxJTkVfS0VZX0JVRkZFUl9TSVpFLTEpOyArK2kpCgkJICAgIHsKCQkJcmVzdWx0W2xlbisrXSA9IHRvW2ldOwoJCQlpZiAodG9baV0gPT0gQ1NJKQoJCQl7CgkJCSAgICByZXN1bHRbbGVuKytdID0gS1NfRVhUUkE7CgkJCSAgICByZXN1bHRbbGVuKytdID0gKGludClLRV9DU0k7CgkJCX0KCQkgICAgfQoJCSAgICB2aW1fZnJlZSh0byk7CgkJfQoKCQlhZGRfdG9faW5wdXRfYnVmKHJlc3VsdCwgbGVuKTsKCQllID0gbm9FcnI7CgkgICAgfQoJICAgIHdoaWxlICgwKTsKCgkgICAgdmltX2ZyZWUodGV4dCk7CgkgICAgaWYgKGUgPT0gbm9FcnIpCgkgICAgewoJCS8qIEZha2UgZXZlbnQgdG8gd2FrZSB1cCBXTkUgKHJlcXVpcmVkIHRvIGdldAoJCSAqIGtleSByZXBlYXQgd29ya2luZyAqLwoJCVBvc3RFdmVudChrZXlVcCwgMCk7CgkJcmV0dXJuIG5vRXJyOwoJICAgIH0KCX0KICAgIH0KICAgIHdoaWxlICgwKTsKCiAgICByZXR1cm4gQ2FsbE5leHRFdmVudEhhbmRsZXIobmV4dEhhbmRsZXIsIHRoZUV2ZW50KTsKfQojZWxzZQogICAgdm9pZApndWlfbWFjX2RvS2V5RXZlbnQoRXZlbnRSZWNvcmQgKnRoZUV2ZW50KQp7CiAgICAvKiBUT0RPOiBhZGQgc3VwcG9ydCBmb3IgQ09NTUFORCBLRVkgKi8KICAgIGxvbmcJCW1lbnU7CiAgICB1bnNpZ25lZCBjaGFyCXN0cmluZ1syMF07CiAgICBzaG9ydAkJbnVtLCBpOwogICAgc2hvcnQJCWxlbiA9IDA7CiAgICBLZXlTeW0JCWtleV9zeW07CiAgICBpbnQJCQlrZXlfY2hhcjsKICAgIGludAkJCW1vZGlmaWVyczsKICAgIGludAkJCXNpbXBsaWZ5ID0gRkFMU0U7CgogICAgLyogTWFzayB0aGUgbW91c2UgKGFzIHBlciB1c2VyIHNldHRpbmcpICovCiAgICBpZiAocF9taCkKCU9ic2N1cmVDdXJzb3IoKTsKCiAgICAvKiBHZXQgdGhlIGtleSBjb2RlIGFuZCBpdCdzIEFTQ0lJIHJlcHJlc2VudGF0aW9uICovCiAgICBrZXlfc3ltID0gKCh0aGVFdmVudC0+bWVzc2FnZSAmIGtleUNvZGVNYXNrKSA+PiA4KTsKICAgIGtleV9jaGFyID0gdGhlRXZlbnQtPm1lc3NhZ2UgJiBjaGFyQ29kZU1hc2s7CiAgICBudW0gPSAxOwoKICAgIC8qIEludGVyY2VwdCBDVFJMLUMgKi8KICAgIGlmICh0aGVFdmVudC0+bW9kaWZpZXJzICYgY29udHJvbEtleSkKICAgIHsKCWlmIChrZXlfY2hhciA9PSBDdHJsX0MgJiYgY3RybF9jX2ludGVycnVwdHMpCgkgICAgZ290X2ludCA9IFRSVUU7CgllbHNlIGlmICgodGhlRXZlbnQtPm1vZGlmaWVycyAmIH4oY29udHJvbEtleXxzaGlmdEtleSkpID09IDAKCQkmJiAoa2V5X2NoYXIgPT0gJzInIHx8IGtleV9jaGFyID09ICc2JykpCgl7CgkgICAgLyogQ1RSTC1eIGFuZCBDVFJMLUAgZG9uJ3Qgd29yayBpbiB0aGUgbm9ybWFsIHdheS4gKi8KCSAgICBpZiAoa2V5X2NoYXIgPT0gJzInKQoJCWtleV9jaGFyID0gQ3RybF9BVDsKCSAgICBlbHNlCgkJa2V5X2NoYXIgPSBDdHJsX0hBVDsKCSAgICB0aGVFdmVudC0+bW9kaWZpZXJzID0gMDsKCX0KICAgIH0KCiAgICAvKiBJbnRlcmNlcHQgQ01ELS4gKi8KICAgIGlmICh0aGVFdmVudC0+bW9kaWZpZXJzICYgY21kS2V5KQoJaWYgKGtleV9jaGFyID09ICcuJykKCSAgICBnb3RfaW50ID0gVFJVRTsKCiAgICAvKiBIYW5kbGUgY29tbWFuZCBrZXkgYXMgcGVyIG1lbnUgKi8KICAgIC8qIFRPRE86IHNob3VsZCBvdmVycmlkZSBiZSBhbGxvd2VkPyBSZXF1aXJlIFlBTyBvciBjb3VsZCB1c2UgJ3dpbmFsdGtleScgKi8KICAgIGlmICh0aGVFdmVudC0+bW9kaWZpZXJzICYgY21kS2V5KQoJLyogT25seSBhY2NlcHQgQ01EIGFsb25lIG9yIHdpdGggQ0FQTE9DS1MgYW5kIHRoZSBtb3VzZSBidXR0b24uCgkgKiBXaHkgdGhlIG1vdXNlIGJ1dHRvbj8gKi8KCWlmICgodGhlRXZlbnQtPm1vZGlmaWVycyAmICh+KGNtZEtleSB8IGJ0blN0YXRlIHwgYWxwaGFMb2NrKSkpID09IDApCgl7CgkgICAgbWVudSA9IE1lbnVLZXkoa2V5X2NoYXIpOwoJICAgIGlmIChIaVdvcmQobWVudSkpCgkgICAgewoJCWd1aV9tYWNfaGFuZGxlX21lbnUobWVudSk7CgkJcmV0dXJuOwoJICAgIH0KCX0KCiAgICAvKiBDb252ZXJ0IHRoZSBtb2RpZmllcnMgKi8KICAgIG1vZGlmaWVycyA9IEV2ZW50TW9kaWZpZXJzMlZpbU1vZGlmaWVycyh0aGVFdmVudC0+bW9kaWZpZXJzKTsKCgogICAgLyogSGFuZGxlIHNwZWNpYWwga2V5cy4gKi8KI2lmIDAKICAgIC8qIFdoeSBoYXMgdGhpcyBiZWVuIHJlbW92ZWQ/ICovCiAgICBpZgkoISh0aGVFdmVudC0+bW9kaWZpZXJzICYgKGNtZEtleSB8IGNvbnRyb2xLZXkgfCByaWdodENvbnRyb2xLZXkpKSkKI2VuZGlmCiAgICB7CgkvKiBGaW5kIHRoZSBzcGVjaWFsIGtleSAoZm9yIG5vbi1wcmludGFibGUga2V5dF9jaGFyKSAqLwoJaWYgICgoa2V5X2NoYXIgPCAweDIwKSB8fCAoa2V5X2NoYXIgPT0gMHg3ZikpCgkgICAgZm9yIChpID0gMDsgc3BlY2lhbF9rZXlzW2ldLmtleV9zeW0gIT0gKEtleVN5bSkwOyBpKyspCgkJaWYgKHNwZWNpYWxfa2V5c1tpXS5rZXlfc3ltID09IGtleV9zeW0pCgkJewojIGlmIDAKCQkgICAgLyogV2UgY3VycmVudGx5IGRvbid0IGhhdmUgbm90IHNvIHNwZWNpYWwga2V5ICovCgkJICAgIGlmIChzcGVjaWFsX2tleXNbaV0udmltX2NvZGUxID09IE5VTCkKCQkJa2V5X2NoYXIgPSBzcGVjaWFsX2tleXNbaV0udmltX2NvZGUwOwoJCSAgICBlbHNlCiMgZW5kaWYKCQkJa2V5X2NoYXIgPSBUT19TUEVDSUFMKHNwZWNpYWxfa2V5c1tpXS52aW1fY29kZTAsCgkJCQkJCXNwZWNpYWxfa2V5c1tpXS52aW1fY29kZTEpOwoJCSAgICBzaW1wbGlmeSA9IFRSVUU7CgkJICAgIGJyZWFrOwoJCX0KICAgIH0KCiAgICAvKiBGb3Igc29tZSBrZXlzIHRoZSBtb2RpZmllciBpcyBpbmNsdWRlZCBpbiB0aGUgY2hhciBpdHNlbGYuICovCiAgICBpZiAoc2ltcGxpZnkgfHwga2V5X2NoYXIgPT0gVEFCIHx8IGtleV9jaGFyID09ICcgJykKCWtleV9jaGFyID0gc2ltcGxpZnlfa2V5KGtleV9jaGFyLCAmbW9kaWZpZXJzKTsKCiAgICAvKiBBZGQgdGhlIG1vZGlmaWVyIHRvIHRoZSBpbnB1dCBidSBpZiBuZWVkZWQgKi8KICAgIC8qIERvIG5vdCB3YW50IFNISUZULUEgb3IgQ1RSTC1BIHdpdGggbW9kaWZpZXIgKi8KICAgIGlmICghSVNfU1BFQ0lBTChrZXlfY2hhcikKCSAgICAmJiBrZXlfc3ltICE9IHZrX1NwYWNlCgkgICAgJiYga2V5X3N5bSAhPSB2a19UYWIKCSAgICAmJiBrZXlfc3ltICE9IHZrX1JldHVybgoJICAgICYmIGtleV9zeW0gIT0gdmtfRW50ZXIKCSAgICAmJiBrZXlfc3ltICE9IHZrX0VzYykKICAgIHsKI2lmIDEKICAgIC8qIENsZWFyIG1vZGlmaWVycyB3aGVuIG9ubHkgb25lIG1vZGlmaWVyIGlzIHNldCAqLwoJaWYgKChtb2RpZmllcnMgPT0gTU9EX01BU0tfU0hJRlQpCgkJfHwgKG1vZGlmaWVycyA9PSBNT0RfTUFTS19DVFJMKQoJCXx8IChtb2RpZmllcnMgPT0gTU9EX01BU0tfQUxUKSkKCSAgICBtb2RpZmllcnMgPSAwOwojZWxzZQoJaWYgKG1vZGlmaWVycyAmIE1PRF9NQVNLX0NUUkwpCgkgICAgbW9kaWZpZXJzID0gbW9kaWZpZXJzICYgfk1PRF9NQVNLX0NUUkw7CglpZiAobW9kaWZpZXJzICYgTU9EX01BU0tfQUxUKQoJICAgIG1vZGlmaWVycyA9IG1vZGlmaWVycyAmIH5NT0RfTUFTS19BTFQ7CglpZiAobW9kaWZpZXJzICYgTU9EX01BU0tfU0hJRlQpCgkgICAgbW9kaWZpZXJzID0gbW9kaWZpZXJzICYgfk1PRF9NQVNLX1NISUZUOwojZW5kaWYKICAgIH0KCWlmIChtb2RpZmllcnMpCgl7CgkgICAgc3RyaW5nW2xlbisrXSA9IENTSTsKCSAgICBzdHJpbmdbbGVuKytdID0gS1NfTU9ESUZJRVI7CgkgICAgc3RyaW5nW2xlbisrXSA9IG1vZGlmaWVyczsKCX0KCglpZiAoSVNfU1BFQ0lBTChrZXlfY2hhcikpCgl7CgkgICAgc3RyaW5nW2xlbisrXSA9IENTSTsKCSAgICBzdHJpbmdbbGVuKytdID0gS19TRUNPTkQoa2V5X2NoYXIpOwoJICAgIHN0cmluZ1tsZW4rK10gPSBLX1RISVJEKGtleV9jaGFyKTsKCX0KCWVsc2UKCXsKI2lmZGVmIEZFQVRfTUJZVEUKCSAgICAvKiBDb252ZXJ0IGNoYXJhY3RlcnMgd2hlbiBuZWVkZWQgKGUuZy4sIGZyb20gTWFjUm9tYW4gdG8gbGF0aW4xKS4KCSAgICAgKiBUaGlzIGRvZXNuJ3Qgd29yayBmb3IgdGhlIE5VTCBieXRlLiAqLwoJICAgIGlmIChpbnB1dF9jb252LnZjX3R5cGUgIT0gQ09OVl9OT05FICYmIGtleV9jaGFyID4gMCkKCSAgICB7CgkJY2hhcl91CWZyb21bMl0sICp0bzsKCQlpbnQJbDsKCgkJZnJvbVswXSA9IGtleV9jaGFyOwoJCWZyb21bMV0gPSBOVUw7CgkJbCA9IDE7CgkJdG8gPSBzdHJpbmdfY29udmVydCgmaW5wdXRfY29udiwgZnJvbSwgJmwpOwoJCWlmICh0byAhPSBOVUxMKQoJCXsKCQkgICAgZm9yIChpID0gMDsgaSA8IGwgJiYgbGVuIDwgMTk7IGkrKykKCQkgICAgewoJCQlpZiAodG9baV0gPT0gQ1NJKQoJCQl7CgkJCSAgICBzdHJpbmdbbGVuKytdID0gS1NfRVhUUkE7CgkJCSAgICBzdHJpbmdbbGVuKytdID0gS0VfQ1NJOwoJCQl9CgkJCWVsc2UKCQkJICAgIHN0cmluZ1tsZW4rK10gPSB0b1tpXTsKCQkgICAgfQoJCSAgICB2aW1fZnJlZSh0byk7CgkJfQoJCWVsc2UKCQkgICAgc3RyaW5nW2xlbisrXSA9IGtleV9jaGFyOwoJICAgIH0KCSAgICBlbHNlCiNlbmRpZgoJCXN0cmluZ1tsZW4rK10gPSBrZXlfY2hhcjsKCX0KCglpZiAobGVuID09IDEgJiYgc3RyaW5nWzBdID09IENTSSkKCXsKCSAgICAvKiBUdXJuIENTSSBpbnRvIEtfQ1NJLiAqLwoJICAgIHN0cmluZ1sgbGVuKysgXSA9IEtTX0VYVFJBOwoJICAgIHN0cmluZ1sgbGVuKysgXSA9IEtFX0NTSTsKCX0KCiAgICBhZGRfdG9faW5wdXRfYnVmKHN0cmluZywgbGVuKTsKfQojZW5kaWYKCi8qCiAqIEhhbmRsZSBNb3VzZUNsaWNrCiAqLwogICAgdm9pZApndWlfbWFjX2RvTW91c2VEb3duRXZlbnQoRXZlbnRSZWNvcmQgKnRoZUV2ZW50KQp7CiAgICBzaG9ydAkJdGhlUGFydDsKICAgIFdpbmRvd1B0cgkJd2hpY2hXaW5kb3c7CgogICAgdGhlUGFydCA9IEZpbmRXaW5kb3codGhlRXZlbnQtPndoZXJlLCAmd2hpY2hXaW5kb3cpOwoKICAgIHN3aXRjaCAodGhlUGFydCkKICAgIHsKCWNhc2UgKGluRGVzayk6CgkgICAgLyogVE9ETzogd2hhdCB0byBkbz8gKi8KCSAgICBicmVhazsKCgljYXNlIChpbk1lbnVCYXIpOgoJICAgIGd1aV9tYWNfaGFuZGxlX21lbnUoTWVudVNlbGVjdCh0aGVFdmVudC0+d2hlcmUpKTsKCSAgICBicmVhazsKCgljYXNlIChpbkNvbnRlbnQpOgoJICAgIGd1aV9tYWNfZG9JbkNvbnRlbnRDbGljayh0aGVFdmVudCwgd2hpY2hXaW5kb3cpOwoJICAgIGJyZWFrOwoKCWNhc2UgKGluRHJhZyk6CgkgICAgZ3VpX21hY19kb0luRHJhZ0NsaWNrKHRoZUV2ZW50LT53aGVyZSwgd2hpY2hXaW5kb3cpOwoJICAgIGJyZWFrOwoKCWNhc2UgKGluR3Jvdyk6CgkgICAgZ3VpX21hY19kb0luR3Jvd0NsaWNrKHRoZUV2ZW50LT53aGVyZSwgd2hpY2hXaW5kb3cpOwoJICAgIGJyZWFrOwoKCWNhc2UgKGluR29Bd2F5KToKCSAgICBpZiAoVHJhY2tHb0F3YXkod2hpY2hXaW5kb3csIHRoZUV2ZW50LT53aGVyZSkpCgkJZ3VpX3NoZWxsX2Nsb3NlZCgpOwoJICAgIGJyZWFrOwoKCWNhc2UgKGluWm9vbUluKToKCWNhc2UgKGluWm9vbU91dCk6CgkgICAgZ3VpX21hY19kb0luWm9vbUNsaWNrKHRoZUV2ZW50LCB3aGljaFdpbmRvdyk7CgkgICAgYnJlYWs7CiAgICB9Cn0KCi8qCiAqIEhhbmRsZSBNb3VzZU1vdmVkCiAqIFt0aGlzIGV2ZW50IGlzIGEgbW92aW5nIGluIGFuZCBvdXQgb2YgYSByZWdpb25dCiAqLwogICAgdm9pZApndWlfbWFjX2RvTW91c2VNb3ZlZEV2ZW50KEV2ZW50UmVjb3JkICpldmVudCkKewogICAgUG9pbnQgICB0aGVQb2ludDsKICAgIGludF91ICAgdmltTW9kaWZpZXJzOwoKICAgIHRoZVBvaW50ID0gZXZlbnQtPndoZXJlOwogICAgR2xvYmFsVG9Mb2NhbCgmdGhlUG9pbnQpOwogICAgdmltTW9kaWZpZXJzID0gRXZlbnRNb2RpZmllcnMyVmltTW91c2VNb2RpZmllcnMoZXZlbnQtPm1vZGlmaWVycyk7CgogICAgaWYgKCFCdXR0b24oKSkKCWd1aV9tb3VzZV9tb3ZlZCh0aGVQb2ludC5oLCB0aGVQb2ludC52KTsKICAgIGVsc2UKCWlmICghY2xpY2tJc1BvcHVwKQoJICAgIGd1aV9zZW5kX21vdXNlX2V2ZW50KE1PVVNFX0RSQUcsIHRoZVBvaW50LmgsCgkJCQkJICAgICB0aGVQb2ludC52LCBGQUxTRSwgdmltTW9kaWZpZXJzKTsKCiAgICAvKiBSZXNldCB0aGUgcmVnaW9uIGZyb20gd2hpY2ggd2UgbW92ZSBpbiBhbmQgb3V0ICovCiAgICBTZXRSZWN0KCZkcmFnUmVjdCwgRklMTF9YKFhfMl9DT0wodGhlUG9pbnQuaCkpLAoJCQlGSUxMX1koWV8yX1JPVyh0aGVQb2ludC52KSksCgkJCUZJTExfWChYXzJfQ09MKHRoZVBvaW50LmgpKzEpLAoJCQlGSUxMX1koWV8yX1JPVyh0aGVQb2ludC52KSsxKSk7CgogICAgaWYgKGRyYWdSZWN0RW5ibCkKCWRyYWdSZWN0Q29udHJvbCA9IGtDcmVhdGVSZWN0OwoKfQoKLyoKICogSGFuZGxlIHRoZSBtb3VzZSByZWxlYXNlCiAqLwogICAgdm9pZApndWlfbWFjX2RvTW91c2VVcEV2ZW50KEV2ZW50UmVjb3JkICp0aGVFdmVudCkKewogICAgUG9pbnQgICB0aGVQb2ludDsKICAgIGludF91ICAgdmltTW9kaWZpZXJzOwoKICAgIC8qIFRPRE86IFByb3Blcmx5IGNvbnZlcnQgdGhlIENvbnRleHR1YWwgbWVudSBtb3VzZS11cCAqLwogICAgLyogICAgICAgUG90ZW50aWFsIHNvdXJjZSBvZiB0aGUgZG91YmxlIG1lbnUgKi8KICAgIGxhc3RNb3VzZVRpY2sgPSB0aGVFdmVudC0+d2hlbjsKICAgIGRyYWdSZWN0RW5ibCA9IEZBTFNFOwogICAgZHJhZ1JlY3RDb250cm9sID0ga0NyZWF0ZUVtcHR5OwogICAgdGhlUG9pbnQgPSB0aGVFdmVudC0+d2hlcmU7CiAgICBHbG9iYWxUb0xvY2FsKCZ0aGVQb2ludCk7CgogICAgdmltTW9kaWZpZXJzID0gRXZlbnRNb2RpZmllcnMyVmltTW91c2VNb2RpZmllcnModGhlRXZlbnQtPm1vZGlmaWVycyk7CiAgICBpZiAoY2xpY2tJc1BvcHVwKQogICAgewoJdmltTW9kaWZpZXJzICY9IH5NT1VTRV9DVFJMOwoJY2xpY2tJc1BvcHVwID0gRkFMU0U7CiAgICB9CiAgICBndWlfc2VuZF9tb3VzZV9ldmVudChNT1VTRV9SRUxFQVNFLCB0aGVQb2ludC5oLCB0aGVQb2ludC52LCBGQUxTRSwgdmltTW9kaWZpZXJzKTsKfQoKICAgIHN0YXRpYyBwYXNjYWwgT1NTdGF0dXMKZ3VpX21hY19tb3VzZV93aGVlbChFdmVudEhhbmRsZXJDYWxsUmVmIG5leHRIYW5kbGVyLCBFdmVudFJlZiB0aGVFdmVudCwKCQkJCQkJCQkgICB2b2lkICpkYXRhKQp7CiAgICBFdmVudFJlZglib2d1c0V2ZW50OwogICAgUG9pbnQJcG9pbnQ7CiAgICBSZWN0CWJvdW5kczsKICAgIFVJbnQzMgltb2Q7CiAgICBTSW50MzIJZGVsdGE7CiAgICBpbnRfdQl2aW1fbW9kOwoKICAgIGlmIChub0VyciAhPSBHZXRFdmVudFBhcmFtZXRlcih0aGVFdmVudCwga0V2ZW50UGFyYW1Nb3VzZVdoZWVsRGVsdGEsCgkJCSAgICAgIHR5cGVTSW50MzIsIE5VTEwsIHNpemVvZihTSW50MzIpLCBOVUxMLCAmZGVsdGEpKQoJZ290byBiYWlsOwogICAgaWYgKG5vRXJyICE9IEdldEV2ZW50UGFyYW1ldGVyKHRoZUV2ZW50LCBrRXZlbnRQYXJhbU1vdXNlTG9jYXRpb24sCgkJCSAgICAgIHR5cGVRRFBvaW50LCBOVUxMLCBzaXplb2YoUG9pbnQpLCBOVUxMLCAmcG9pbnQpKQoJZ290byBiYWlsOwogICAgaWYgKG5vRXJyICE9IEdldEV2ZW50UGFyYW1ldGVyKHRoZUV2ZW50LCBrRXZlbnRQYXJhbUtleU1vZGlmaWVycywKCQkJCXR5cGVVSW50MzIsIE5VTEwsIHNpemVvZihVSW50MzIpLCBOVUxMLCAmbW9kKSkKCWdvdG8gYmFpbDsKCiAgICB2aW1fbW9kID0gMDsKICAgIGlmIChtb2QgJiBzaGlmdEtleSkKCXZpbV9tb2QgfD0gTU9VU0VfU0hJRlQ7CiAgICBpZiAobW9kICYgY29udHJvbEtleSkKCXZpbV9tb2QgfD0gTU9VU0VfQ1RSTDsKICAgIGlmIChtb2QgJiBvcHRpb25LZXkpCgl2aW1fbW9kIHw9IE1PVVNFX0FMVDsKCiAgICAvKiBwb3N0IGEgYm9ndXMgZXZlbnQgdG8gd2FrZSB1cCBXYWl0TmV4dEV2ZW50ICovCiAgICBpZiAobm9FcnIgIT0gQ3JlYXRlRXZlbnQoTlVMTCwga0V2ZW50Q2xhc3NNb3VzZSwga0V2ZW50TW91c2VNb3ZlZCwgMCwKCQkJCQkgICAga0V2ZW50QXR0cmlidXRlTm9uZSwgJmJvZ3VzRXZlbnQpKQoJZ290byBiYWlsOwogICAgaWYgKG5vRXJyICE9IFBvc3RFdmVudFRvUXVldWUoR2V0TWFpbkV2ZW50UXVldWUoKSwgYm9ndXNFdmVudCwKCQkJCQkJCSAgIGtFdmVudFByaW9yaXR5TG93KSkKCWdvdG8gYmFpbDsKCiAgICBSZWxlYXNlRXZlbnQoYm9ndXNFdmVudCk7CgogICAgaWYgKG5vRXJyID09IEdldFdpbmRvd0JvdW5kcyhndWkuVmltV2luZG93LCBrV2luZG93Q29udGVudFJnbiwgJmJvdW5kcykpCiAgICB7Cglwb2ludC5oIC09IGJvdW5kcy5sZWZ0OwoJcG9pbnQudiAtPSBib3VuZHMudG9wOwogICAgfQoKICAgIGd1aV9zZW5kX21vdXNlX2V2ZW50KChkZWx0YSA+IDApID8gTU9VU0VfNCA6IE1PVVNFXzUsCgkJCQkJICAgIHBvaW50LmgsIHBvaW50LnYsIEZBTFNFLCB2aW1fbW9kKTsKCiAgICByZXR1cm4gbm9FcnI7CgogIGJhaWw6CiAgICAvKgogICAgICogd2hlbiB3ZSBmYWlsIGdpdmUgYW55IGFkZGl0aW9uYWwgY2FsbGJhY2sgaGFuZGxlciBhIGNoYW5jZSB0byBwZXJmb3JtCiAgICAgKiBpdCdzIGFjdGlvbnMKICAgICAqLwogICAgcmV0dXJuIENhbGxOZXh0RXZlbnRIYW5kbGVyKG5leHRIYW5kbGVyLCB0aGVFdmVudCk7Cn0KCiNpZiAwCgovKgogKiBUaGlzIHdvdWxkIGJlIHRoZSBub3JtYWwgd2F5IG9mIGludm9raW5nIHRoZSBjb250ZXh0dWFsIG1lbnUKICogYnV0IHRoZSBWaW0gQVBJIGRvZXNuJ3Qgc2VlbSB0byBhIHN1cHBvcnQgYSByZXF1ZXN0IHRvIGdldAogKiB0aGUgbWVudSB0aGF0IHdlIHNob3VsZCBkaXNwbGF5CiAqLwogICAgdm9pZApndWlfbWFjX2hhbmRsZV9jb250ZXh0dWFsX21lbnUoZXZlbnQpCiAgICBFdmVudFJlY29yZCAqZXZlbnQ7CnsKLyoKICogIENsb25lIFBvcFVwIHRvIHVzZSBtZW51CiAqICBDcmVhdGUgYSBvYmplY3QgZGVzY3JpcHRvciBmb3IgdGhlIGN1cnJlbnQgc2VsZWN0aW9uCiAqICBDYWxsIHRoZSBwcm9jZWR1cmUKICovCgovLyAgQ2FsbCB0byBIYW5kbGUgUG9wdXAKICAgIE9TU3RhdHVzIHN0YXR1cyA9IENvbnRleHR1YWxNZW51U2VsZWN0KENudHhNZW51LCBldmVudC0+d2hlcmUsIGZhbHNlLCBrQ01IZWxwSXRlbU5vSGVscCwgIiIsIE5VTEwsICZDbnR4VHlwZSwgJkNudHhNZW51SUQsICZDbnR4TWVudUl0ZW0pOwoKICAgIGlmIChzdGF0dXMgIT0gbm9FcnIpCglyZXR1cm47CgogICAgaWYgKENudHhUeXBlID09IGtDTU1lbnVJdGVtU2VsZWN0ZWQpCiAgICB7CgkvKiBIYW5kbGUgdGhlIG1lbnUgQ250eE1lbnVJRCwgQ250eE1lbnVJdGVtICovCgkvKiBUaGUgc3VibWVudSBjYW4gYmUgaGFuZGxlIGRpcmVjdGx5IGJ5IGd1aV9tYWNfaGFuZGxlX21lbnUgKi8KCS8qIEJ1dCB3aGF0IGFib3V0IHRoZSBjdXJyZW50IG1lbnUsIGlzIHRoZSBtZW55IGNoYW5nZWQgYnkgQ29udGV4dHVhbE1lbnVTZWxlY3QgKi8KCWd1aV9tYWNfaGFuZGxlX21lbnUoKENudHhNZW51SUQgPDwgMTYpICsgQ250eE1lbnVJdGVtKTsKICAgIH0KICAgIGVsc2UgaWYgKENudHhNZW51SUQgPT0ga0NNU2hvd0hlbHBTZWxlY3RlZCkKICAgIHsKCS8qIFNob3VsZCBjb21lIHVwIHdpdGggdGhlIGhlbHAgKi8KICAgIH0KCn0KI2VuZGlmCgovKgogKiBIYW5kbGUgbWVudWJhciBzZWxlY3Rpb24KICovCiAgICB2b2lkCmd1aV9tYWNfaGFuZGxlX21lbnUobG9uZyBtZW51Q2hvaWNlKQp7CiAgICBzaG9ydAltZW51ID0gSGlXb3JkKG1lbnVDaG9pY2UpOwogICAgc2hvcnQJaXRlbSA9IExvV29yZChtZW51Q2hvaWNlKTsKICAgIHZpbW1lbnVfVAkqdGhlVmltTWVudSA9IHJvb3RfbWVudTsKCiAgICBpZiAobWVudSA9PSAyNTYpICAvKiBUT0RPOiB1c2UgY29uc3RhbnQgb3IgZ3VpLnh5eiAqLwogICAgewoJaWYgKGl0ZW0gPT0gMSkKCSAgICBndWlfbWNoX2JlZXAoKTsgLyogVE9ETzogUG9wdXAgZGlhbG9nIG9yIGRvIDppbnRybyAqLwogICAgfQogICAgZWxzZSBpZiAoaXRlbSAhPSAwKQogICAgewoJdGhlVmltTWVudSA9IGd1aV9tYWNfZ2V0X3ZpbV9tZW51KG1lbnUsIGl0ZW0sIHJvb3RfbWVudSk7CgoJaWYgKHRoZVZpbU1lbnUpCgkgICAgZ3VpX21lbnVfY2IodGhlVmltTWVudSk7CiAgICB9CiAgICBIaWxpdGVNZW51KDApOwp9CgovKgogKiBEaXNwYXRjaCB0aGUgZXZlbnQgdG8gcHJvcGVyIGhhbmRsZXIKICovCgogICAgdm9pZApndWlfbWFjX2hhbmRsZV9ldmVudChFdmVudFJlY29yZCAqZXZlbnQpCnsKICAgIE9TRXJyCWVycm9yOwoKICAgIC8qIEhhbmRsZSBjb250ZXh0dWFsIG1lbnUgcmlnaHQgbm93IChpZiBuZWVkZWQpICovCiAgICBpZiAoZ3VpLk1hY09TSGF2ZUNudHhNZW51KQoJaWYgKElzU2hvd0NvbnRleHR1YWxNZW51Q2xpY2soZXZlbnQpKQoJewojIGlmIDAKCSAgICBndWlfbWFjX2hhbmRsZV9jb250ZXh0dWFsX21lbnUoZXZlbnQpOwojIGVsc2UKCSAgICBndWlfbWFjX2RvTW91c2VEb3duRXZlbnQoZXZlbnQpOwojIGVuZGlmCgkgICAgcmV0dXJuOwoJfQoKICAgIC8qIEhhbmRsZSBub3JtYWwgZXZlbnQgKi8KICAgIHN3aXRjaCAoZXZlbnQtPndoYXQpCiAgICB7CiNpZm5kZWYgVVNFX0NBUkJPTktFWUhBTkRMRVIKCWNhc2UgKGtleURvd24pOgoJY2FzZSAoYXV0b0tleSk6CgkgICAgZ3VpX21hY19kb0tleUV2ZW50KGV2ZW50KTsKCSAgICBicmVhazsKI2VuZGlmCgljYXNlIChrZXlVcCk6CgkgICAgLyogV2UgZG9uJ3QgY2FyZSBhYm91dCB3aGVuIHRoZSBrZXkgaXMgcmVsZWFzZWQgKi8KCSAgICBicmVhazsKCgljYXNlIChtb3VzZURvd24pOgoJICAgIGd1aV9tYWNfZG9Nb3VzZURvd25FdmVudChldmVudCk7CgkgICAgYnJlYWs7CgoJY2FzZSAobW91c2VVcCk6CgkgICAgZ3VpX21hY19kb01vdXNlVXBFdmVudChldmVudCk7CgkgICAgYnJlYWs7CgoJY2FzZSAodXBkYXRlRXZ0KToKCSAgICBndWlfbWFjX2RvVXBkYXRlRXZlbnQoZXZlbnQpOwoJICAgIGJyZWFrOwoKCWNhc2UgKGRpc2tFdnQpOgoJICAgIC8qIFdlIGRvbid0IG5lZWQgc3BlY2lhbCBoYW5kbGluZyBmb3IgZGlzayBpbnNlcnRpb24gKi8KCSAgICBicmVhazsKCgljYXNlIChhY3RpdmF0ZUV2dCk6CgkgICAgZ3VpX21hY19kb0FjdGl2YXRlRXZlbnQoZXZlbnQpOwoJICAgIGJyZWFrOwoKCWNhc2UgKG9zRXZ0KToKCSAgICBzd2l0Y2ggKChldmVudC0+bWVzc2FnZSA+PiAyNCkgJiAweEZGKQoJICAgIHsKCQljYXNlICgweEZBKTogLyogbW91c2VNb3ZlZE1lc3NhZ2UgKi8KCQkgICAgZ3VpX21hY19kb01vdXNlTW92ZWRFdmVudChldmVudCk7CgkJICAgIGJyZWFrOwoJCWNhc2UgKDB4MDEpOiAvKiBzdXNwZW5kUmVzdW1lTWVzc2FnZSAqLwoJCSAgICBndWlfbWFjX2RvU3VzcGVuZEV2ZW50KGV2ZW50KTsKCQkgICAgYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoKI2lmZGVmIFVTRV9BRVZFTlQKCWNhc2UgKGtIaWdoTGV2ZWxFdmVudCk6CgkgICAgLyogU29tZW9uZSdzIHRhbGtpbmcgdG8gdXMsIHRocm91Z2ggQXBwbGVFdmVudHMgKi8KCSAgICBlcnJvciA9IEFFUHJvY2Vzc0FwcGxlRXZlbnQoZXZlbnQpOyAvKiBUT0RPOiBFcnJvciBIYW5kbGluZyAqLwoJICAgIGJyZWFrOwojZW5kaWYKICAgIH0KfQoKLyoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFVua25vd24gU3R1ZmYKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKCiAgICBHdWlGb250Cmd1aV9tYWNfZmluZF9mb250KGNoYXJfdSAqZm9udF9uYW1lKQp7CiAgICBjaGFyX3UJYzsKICAgIGNoYXJfdQkqcDsKICAgIGNoYXJfdQlwRm9udE5hbWVbMjU2XTsKICAgIFN0cjI1NQlzeXN0ZW1Gb250bmFtZTsKICAgIHNob3J0CWZvbnRfaWQ7CiAgICBzaG9ydAlzaXplPTk7CiAgICBHdWlGb250CWZvbnQ7CiNpZiAwCiAgICBjaGFyX3UgICAgICAqZm9udE5hbWVQdHI7CiNlbmRpZgoKICAgIGZvciAocCA9IGZvbnRfbmFtZTsgKCgqcCAhPSAwKSAmJiAoKnAgIT0gJzonKSk7IHArKykKCTsKCiAgICBjID0gKnA7CiAgICAqcCA9IDA7CgojaWYgMQogICAgU1RSQ1BZKCZwRm9udE5hbWVbMV0sIGZvbnRfbmFtZSk7CiAgICBwRm9udE5hbWVbMF0gPSBTVFJMRU4oZm9udF9uYW1lKTsKICAgICpwID0gYzsKCiAgICAvKiBHZXQgdGhlIGZvbnQgbmFtZSwgbWludXMgdGhlIHN0eWxlIHN1ZmZpeCAoOmgsIGV0YykgKi8KICAgIGNoYXJfdSBmb250TmFtZVsyNTZdOwogICAgY2hhcl91ICpzdHlsZVN0YXJ0ID0gdmltX3N0cmNocihmb250X25hbWUsICc6Jyk7CiAgICBzaXplX3QgZm9udE5hbWVMZW4gPSBzdHlsZVN0YXJ0ID8gc3R5bGVTdGFydCAtIGZvbnRfbmFtZSA6IFNUUkxFTihmb250TmFtZSk7CiAgICB2aW1fc3RybmNweShmb250TmFtZSwgZm9udF9uYW1lLCBmb250TmFtZUxlbik7CgogICAgQVRTVUZvbnRJRCBmb250UmVmOwogICAgRk1Gb250U3R5bGUgZm9udFN0eWxlOwogICAgZm9udF9pZCA9IDA7CgogICAgaWYgKEFUU1VGaW5kRm9udEZyb21OYW1lKCZwRm9udE5hbWVbMV0sIHBGb250TmFtZVswXSwga0ZvbnRGdWxsTmFtZSwKCQlrRm9udE1hY2ludG9zaFBsYXRmb3JtLCBrRm9udE5vU2NyaXB0Q29kZSwga0ZvbnROb0xhbmd1YWdlQ29kZSwKCQkmZm9udFJlZikgPT0gbm9FcnIpCiAgICB7CglpZiAoRk1HZXRGb250RmFtaWx5SW5zdGFuY2VGcm9tRm9udChmb250UmVmLCAmZm9udF9pZCwgJmZvbnRTdHlsZSkgIT0gbm9FcnIpCgkgICAgZm9udF9pZCA9IDA7CiAgICB9CgogICAgaWYgKGZvbnRfaWQgPT0gMCkKICAgIHsKCS8qCgkgKiBUcnkgYWdhaW4sIHRoaXMgdGltZSByZXBsYWNpbmcgdW5kZXJzY29yZXMgaW4gdGhlIGZvbnQgbmFtZQoJICogd2l0aCBzcGFjZXMgKDpzZXQgZ3VpZm9udCBhbGxvd3MgdGhlIHR3byB0byBiZSB1c2VkCgkgKiBpbnRlcmNoYW5nZWFibHk7IHRoZSBGb250IE1hbmFnZXIgZG9lc24ndCkuCgkgKi8KCWludCBpLCBjaGFuZ2VkID0gRkFMU0U7CgoJZm9yIChpID0gcEZvbnROYW1lWzBdOyBpID4gMDsgLS1pKQoJewoJICAgIGlmIChwRm9udE5hbWVbaV0gPT0gJ18nKQoJICAgIHsKCQlwRm9udE5hbWVbaV0gPSAnICc7CgkJY2hhbmdlZCA9IFRSVUU7CgkgICAgfQoJfQoJaWYgKGNoYW5nZWQpCgkgICAgaWYgKEFUU1VGaW5kRm9udEZyb21OYW1lKCZwRm9udE5hbWVbMV0sIHBGb250TmFtZVswXSwKCQkJa0ZvbnRGdWxsTmFtZSwga0ZvbnROb1BsYXRmb3JtQ29kZSwga0ZvbnROb1NjcmlwdENvZGUsCgkJCWtGb250Tm9MYW5ndWFnZUNvZGUsICZmb250UmVmKSA9PSBub0VycikKCSAgICB7CgkJaWYgKEZNR2V0Rm9udEZhbWlseUluc3RhbmNlRnJvbUZvbnQoZm9udFJlZiwgJmZvbnRfaWQsICZmb250U3R5bGUpICE9IG5vRXJyKQoJCSAgICBmb250X2lkID0gMDsKCSAgICB9CiAgICB9CgojZWxzZQogICAgLyogbmFtZSA9IEMyUGFzY2FsX3NhdmUobWVudS0+ZG5hbWUpOyAqLwogICAgZm9udE5hbWVQdHIgPSBDMlBhc2NhbF9zYXZlX2FuZF9yZW1vdmVfYmFja3NsYXNoKGZvbnRfbmFtZSk7CgogICAgR2V0Rk51bShmb250TmFtZVB0ciwgJmZvbnRfaWQpOwojZW5kaWYKCgogICAgaWYgKGZvbnRfaWQgPT0gMCkKICAgIHsKCS8qIE91cHMsIHRoZSBzeXN0ZW0gZm9udCB3YXMgaXQgdGhlIG9uZSB0aGUgdXNlciB3YW50ICovCgoJaWYgKEZNR2V0Rm9udEZhbWlseU5hbWUoc3lzdGVtRm9udCwgc3lzdGVtRm9udG5hbWUpICE9IG5vRXJyKQoJICAgIHJldHVybiBOT0ZPTlQ7CglpZiAoIUVxdWFsU3RyaW5nKHBGb250TmFtZSwgc3lzdGVtRm9udG5hbWUsIGZhbHNlLCBmYWxzZSkpCgkgICAgcmV0dXJuIE5PRk9OVDsKICAgIH0KICAgIGlmICgqcCA9PSAnOicpCiAgICB7CglwKys7CgkvKiBTZXQgdGhlIHZhbHVlcyBmb3VuZCBhZnRlciAnOicgKi8KCXdoaWxlICgqcCkKCXsKCSAgICBzd2l0Y2ggKCpwKyspCgkgICAgewoJCWNhc2UgJ2gnOgoJCSAgICBzaXplID0gcG9pbnRzX3RvX3BpeGVscyhwLCAmcCwgVFJVRSk7CgkJICAgIGJyZWFrOwoJCSAgICAvKgoJCSAgICAgKiBUT0RPOiBNYXliZSBhY2NlcHQgd2lkdGggYW5kIHN0eWxlcwoJCSAgICAgKi8KCSAgICB9CgkgICAgd2hpbGUgKCpwID09ICc6JykKCQlwKys7Cgl9CiAgICB9CgogICAgaWYgKHNpemUgPCAxKQoJc2l6ZSA9IDE7ICAgLyogQXZvaWQgaGF2aW5nIGEgc2l6ZSBvZiAwIHdpdGggc3lzdGVtIGZvbnQgKi8KCiAgICBmb250ID0gKHNpemUgPDwgMTYpICsgKChsb25nKSBmb250X2lkICYgMHhGRkZGKTsKCiAgICByZXR1cm4gZm9udDsKfQoKLyoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIEdVSV9NQ0ggZnVuY3Rpb25uYWxpdHkKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKLyoKICogUGFyc2UgdGhlIEdVSSByZWxhdGVkIGNvbW1hbmQtbGluZSBhcmd1bWVudHMuICBBbnkgYXJndW1lbnRzIHVzZWQgYXJlCiAqIGRlbGV0ZWQgZnJvbSBhcmd2LCBhbmQgKmFyZ2MgaXMgZGVjcmVtZW50ZWQgYWNjb3JkaW5nbHkuICBUaGlzIGlzIGNhbGxlZAogKiB3aGVuIHZpbSBpcyBzdGFydGVkLCB3aGV0aGVyIG9yIG5vdCB0aGUgR1VJIGhhcyBiZWVuIHN0YXJ0ZWQuCiAqLwogICAgdm9pZApndWlfbWNoX3ByZXBhcmUoaW50ICphcmdjLCBjaGFyICoqYXJndikKewogICAgLyogVE9ETzogTW92ZSBtb3N0IG9mIHRoaXMgc3R1ZmYgdG93YXJkIGd1aV9tY2hfaW5pdCAqLwojaWZkZWYgVVNFX0VYRV9OQU1FCiAgICBGU1NwZWMJYXBwbERpcjsKIyBpZm5kZWYgVVNFX0ZJTkRfQlVORExFX1BBVEgKICAgIHNob3J0CWFwcGxWUmVmTnVtOwogICAgbG9uZwlhcHBsRGlySUQ7CiAgICBTdHIyNTUJdm9sTmFtZTsKIyBlbHNlCiAgICBQcm9jZXNzU2VyaWFsTnVtYmVyIHBzbjsKICAgIEZTUmVmCWFwcGxGU1JlZjsKIyBlbmRpZgojZW5kaWYKCiAgICAvKiBXaHkgZGlkIEkgcHV0IHRoYXQgaW4/IChEYW55KSAqLwogICAgTW9yZU1hc3RlclBvaW50ZXJzICgweDQwICogMyk7IC8qIHdlIGxvdmUgaGFuZGxlcyAqLwoKI2lmIDAKICAgIEluaXRDdXJzb3IoKTsKCiAgICBSZWdpc3RlckFwcGVhcmFuY2VDbGllbnQoKTsKCiNpZmRlZiBVU0VfQUVWRU5UCiAgICAodm9pZCkgSW5zdGFsbEFFSGFuZGxlcnMoKTsKI2VuZGlmCgogICAgaWYgKEdlc3RhbHQoZ2VzdGFsdENvbnRleHR1YWxNZW51QXR0ciwgJmdlc3RhbHRfcmMpID09IG5vRXJyKQoJZ3VpLk1hY09TSGF2ZUNudHhNZW51ID0gQml0VHN0KCZnZXN0YWx0X3JjLCAzMS1nZXN0YWx0Q29udGV4dHVhbE1lbnVUcmFwQXZhaWxhYmxlKTsKICAgIGVsc2UKCWd1aS5NYWNPU0hhdmVDbnR4TWVudSA9IGZhbHNlOwoKICAgIGlmIChndWkuTWFjT1NIYXZlQ250eE1lbnUpCglndWkuTWFjT1NIYXZlQ250eE1lbnUgPSAoSW5pdENvbnRleHR1YWxNZW51cygpPT1ub0Vycik7CgogICAgcG9tbWUgPSBOZXdNZW51KDI1NiwgIlxwXDAyNCIpOyAvKiAweDE0PSA9IEFwcGxlIE1lbnUgKi8KCiAgICBBcHBlbmRNZW51KHBvbW1lLCAiXHBBYm91dCBWSU0iKTsKCiAgICBJbnNlcnRNZW51KHBvbW1lLCAwKTsKCiAgICBEcmF3TWVudUJhcigpOwoKCiNpZm5kZWYgVVNFX09GRlNFVEVEX1dJTkRPVwogICAgU2V0UmVjdCgmd2luZFJlY3QsIDEwLCA0OCwgMTArODAqNyArIDE2LCA0OCsyNCoxMSk7CiNlbHNlCiAgICBTZXRSZWN0KCZ3aW5kUmVjdCwgMzAwLCA0MCwgMzAwKzgwKjcgKyAxNiwgNDArMjQqMTEpOwojZW5kaWYKCgogICAgQ3JlYXRlTmV3V2luZG93KGtEb2N1bWVudFdpbmRvd0NsYXNzLAoJCWtXaW5kb3dSZXNpemFibGVBdHRyaWJ1dGUgfCBrV2luZG93Q29sbGFwc2VCb3hBdHRyaWJ1dGUsCgkJJndpbmRSZWN0LCAmZ3VpLlZpbVdpbmRvdyk7CiAgICBTZXRQb3J0V2luZG93UG9ydChndWkuVmltV2luZG93KTsKCiAgICBndWkuY2hhcl93aWR0aCA9IDc7CiAgICBndWkuY2hhcl9oZWlnaHQgPSAxMTsKICAgIGd1aS5jaGFyX2FzY2VudCA9IDY7CiAgICBndWkubnVtX3Jvd3MgPSAyNDsKICAgIGd1aS5udW1fY29scyA9IDgwOwogICAgZ3VpLmluX2ZvY3VzID0gVFJVRTsgLyogRm9yIHRoZSBtb21lbnQgLT4gc3luLiBvZiBmcm9udCBhcHBsaWNhdGlvbiAqLwoKICAgIGdTY3JvbGxBY3Rpb24gPSBOZXdDb250cm9sQWN0aW9uVVBQKGd1aV9tYWNfc2Nyb2xsX2FjdGlvbik7CiAgICBnU2Nyb2xsRHJhZyAgID0gTmV3Q29udHJvbEFjdGlvblVQUChndWlfbWFjX2RyYWdfdGh1bWIpOwoKICAgIGRyYWdSZWN0RW5ibCA9IEZBTFNFOwogICAgZHJhZ1JnbiA9IE5VTEw7CiAgICBkcmFnUmVjdENvbnRyb2wgPSBrQ3JlYXRlRW1wdHk7CiAgICBjdXJzb3JSZ24gPSBOZXdSZ24oKTsKI2VuZGlmCiNpZmRlZiBVU0VfRVhFX05BTUUKIyBpZm5kZWYgVVNFX0ZJTkRfQlVORExFX1BBVEgKICAgIEhHZXRWb2wodm9sTmFtZSwgJmFwcGxWUmVmTnVtLCAmYXBwbERpcklEKTsKICAgIC8qIFROMjAxNTogbWVudGlvbiBhIHBvc3NpYmxlIGJhZCBWUmVmTnVtICovCiAgICBGU01ha2VGU1NwZWMoYXBwbFZSZWZOdW0sIGFwcGxEaXJJRCwgIlxwIiwgJmFwcGxEaXIpOwojIGVsc2UKICAgIC8qIE9TRXJyIEdldEFwcGxpY2F0aW9uQnVuZGxlRlNTcGVjKEZTU3BlY1B0ciB0aGVGU1NwZWNQdHIpCiAgICAgKiBvZiBUTjIwMTUKICAgICAqIFRoaXMgdGVjaG5pYyByZW1vdmUgdGhlIC4uL0NvbnRlbnRzL01hY09TL2V0YyBwYXJ0CiAgICAgKi8KICAgICh2b2lkKUdldEN1cnJlbnRQcm9jZXNzKCZwc24pOwogICAgLyogaWYgKGVyciAhPSBub0VycikgcmV0dXJuIGVycjsgKi8KCiAgICAodm9pZClHZXRQcm9jZXNzQnVuZGxlTG9jYXRpb24oJnBzbiwgJmFwcGxGU1JlZik7CiAgICAvKiBpZiAoZXJyICE9IG5vRXJyKSByZXR1cm4gZXJyOyAqLwoKICAgICh2b2lkKUZTR2V0Q2F0YWxvZ0luZm8oJmFwcGxGU1JlZiwga0ZTQ2F0SW5mb05vbmUsIE5VTEwsIE5VTEwsICZhcHBsRGlyLCBOVUxMKTsKCiAgICAvKiBUaGlzIHRlY2huaWMgcmV0dXJuIE5JTCB3aGVuIHdlIGRpc2FsbG93X2d1aSAqLwojIGVuZGlmCiAgICBleGVfbmFtZSA9IEZ1bGxQYXRoRnJvbUZTU3BlY19zYXZlKGFwcGxEaXIpOwojZW5kaWYKfQoKI2lmbmRlZiBBTFdBWVNfVVNFX0dVSQovKgogKiBDaGVjayBpZiB0aGUgR1VJIGNhbiBiZSBzdGFydGVkLiAgQ2FsbGVkIGJlZm9yZSBndmltcmMgaXMgc291cmNlZC4KICogUmV0dXJuIE9LIG9yIEZBSUwuCiAqLwogICAgaW50Cmd1aV9tY2hfaW5pdF9jaGVjayh2b2lkKQp7CiAgICAvKiBUT0RPOiBGb3IgTWFjT1MgWCBmaW5kIGEgd2F5IHRvIHJldHVybiBGQUlMLCBpZiB0aGUgdXNlciBsb2dnZWQgaW4KICAgICAqIHVzaW5nIHRoZSA+Y29uc29sZQogICAgICovCiAgICBpZiAoZGlzYWxsb3dfZ3VpKSAvKiBzZWUgbWFpbi5jIGZvciByZWFzb24gdG8gZGlzYWxsb3cgKi8KCXJldHVybiBGQUlMOwogICAgcmV0dXJuIE9LOwp9CiNlbmRpZgoKICAgIHN0YXRpYyBPU0VycgpyZWNlaXZlSGFuZGxlcihXaW5kb3dSZWYgdGhlV2luZG93LCB2b2lkKiBoYW5kbGVyUmVmQ29uLCBEcmFnUmVmIHRoZURyYWcpCnsKICAgIGludAkJeCwgeTsKICAgIGludF91CW1vZGlmaWVyczsKICAgIGNoYXJfdQkqKmZuYW1lcyA9IE5VTEw7CiAgICBpbnQJCWNvdW50OwogICAgaW50CQlpLCBqOwoKICAgIC8qIEdldCBkcm9wIHBvc2l0aW9uLCBtb2RpZmllcnMgYW5kIGNvdW50IG9mIGl0ZW1zICovCiAgICB7CglQb2ludAlwb2ludDsKCVNJbnQxNgltb3VzZVVwTW9kaWZpZXJzOwoJVUludDE2CWNvdW50SXRlbTsKCglHZXREcmFnTW91c2UodGhlRHJhZywgJnBvaW50LCBOVUxMKTsKCUdsb2JhbFRvTG9jYWwoJnBvaW50KTsKCXggPSBwb2ludC5oOwoJeSA9IHBvaW50LnY7CglHZXREcmFnTW9kaWZpZXJzKHRoZURyYWcsIE5VTEwsIE5VTEwsICZtb3VzZVVwTW9kaWZpZXJzKTsKCW1vZGlmaWVycyA9IEV2ZW50TW9kaWZpZXJzMlZpbU1vdXNlTW9kaWZpZXJzKG1vdXNlVXBNb2RpZmllcnMpOwoJQ291bnREcmFnSXRlbXModGhlRHJhZywgJmNvdW50SXRlbSk7Cgljb3VudCA9IGNvdW50SXRlbTsKICAgIH0KCiAgICBmbmFtZXMgPSAoY2hhcl91ICoqKWFsbG9jKGNvdW50ICogc2l6ZW9mKGNoYXJfdSAqKSk7CiAgICBpZiAoZm5hbWVzID09IE5VTEwpCglyZXR1cm4gZHJhZ05vdEFjY2VwdGVkRXJyOwoKICAgIC8qIEdldCBmaWxlIG5hbWVzIGRyb3BwZWQgKi8KICAgIGZvciAoaSA9IGogPSAwOyBpIDwgY291bnQ7ICsraSkKICAgIHsKCURyYWdJdGVtUmVmCWl0ZW07CglPU0VycgkJZXJyOwoJU2l6ZQkJc2l6ZTsKCUZsYXZvclR5cGUJdHlwZSA9IGZsYXZvclR5cGVIRlM7CglIRlNGbGF2b3IJaGZzRmxhdm9yOwoKCWZuYW1lc1tpXSA9IE5VTEw7CglHZXREcmFnSXRlbVJlZmVyZW5jZU51bWJlcih0aGVEcmFnLCBpICsgMSwgJml0ZW0pOwoJZXJyID0gR2V0Rmxhdm9yRGF0YVNpemUodGhlRHJhZywgaXRlbSwgdHlwZSwgJnNpemUpOwoJaWYgKGVyciAhPSBub0VyciB8fCBzaXplID4gc2l6ZW9mKGhmc0ZsYXZvcikpCgkgICAgY29udGludWU7CgllcnIgPSBHZXRGbGF2b3JEYXRhKHRoZURyYWcsIGl0ZW0sIHR5cGUsICZoZnNGbGF2b3IsICZzaXplLCAwKTsKCWlmIChlcnIgIT0gbm9FcnIpCgkgICAgY29udGludWU7CglmbmFtZXNbaisrXSA9IEZ1bGxQYXRoRnJvbUZTU3BlY19zYXZlKGhmc0ZsYXZvci5maWxlU3BlYyk7CiAgICB9CiAgICBjb3VudCA9IGo7CgogICAgZ3VpX2hhbmRsZV9kcm9wKHgsIHksIG1vZGlmaWVycywgZm5hbWVzLCBjb3VudCk7CgogICAgLyogRmFrZSBtb3VzZSBldmVudCB0byB3YWtlIGZyb20gc3RhbGwgKi8KICAgIFBvc3RFdmVudChtb3VzZVVwLCAwKTsKCiAgICByZXR1cm4gbm9FcnI7Cn0KCi8qCiAqIEluaXRpYWxpc2UgdGhlIEdVSS4gIENyZWF0ZSBhbGwgdGhlIHdpbmRvd3MsIHNldCB1cCBhbGwgdGhlIGNhbGwtYmFja3MKICogZXRjLgogKi8KICAgIGludApndWlfbWNoX2luaXQodm9pZCkKewogICAgLyogVE9ETzogTW92ZSBtb3N0IG9mIHRoaXMgc3R1ZmYgdG93YXJkIGd1aV9tY2hfaW5pdCAqLwogICAgUmVjdAl3aW5kUmVjdDsKICAgIE1lbnVIYW5kbGUJcG9tbWU7CiAgICBsb25nCWdlc3RhbHRfcmM7CiAgICBFdmVudFR5cGVTcGVjICAgZXZlbnRUeXBlU3BlYzsKICAgIEV2ZW50SGFuZGxlclJlZiBtb3VzZVdoZWVsSGFuZGxlclJlZjsKI2lmZGVmIFVTRV9DQVJCT05LRVlIQU5ETEVSCiAgICBFdmVudEhhbmRsZXJSZWYga2V5RXZlbnRIYW5kbGVyUmVmOwojZW5kaWYKCiAgICBpZiAoR2VzdGFsdChnZXN0YWx0U3lzdGVtVmVyc2lvbiwgJmdNYWNTeXN0ZW1WZXJzaW9uKSAhPSBub0VycikKCWdNYWNTeXN0ZW1WZXJzaW9uID0gMHgxMDAwOyAvKiBUT0RPOiBEZWZhdWx0IHRvIG1pbmltdW0gc2Vuc2libGUgdmFsdWUgKi8KCiNpZiAxCiAgICBJbml0Q3Vyc29yKCk7CgogICAgUmVnaXN0ZXJBcHBlYXJhbmNlQ2xpZW50KCk7CgojaWZkZWYgVVNFX0FFVkVOVAogICAgKHZvaWQpIEluc3RhbGxBRUhhbmRsZXJzKCk7CiNlbmRpZgoKICAgIC8qIEN0cmwgY2xpY2sgKi8KICAgIGlmIChHZXN0YWx0KGdlc3RhbHRDb250ZXh0dWFsTWVudUF0dHIsICZnZXN0YWx0X3JjKSA9PSBub0VycikKCWd1aS5NYWNPU0hhdmVDbnR4TWVudSA9IEJpdFRzdCgmZ2VzdGFsdF9yYywgMzEtZ2VzdGFsdENvbnRleHR1YWxNZW51VHJhcEF2YWlsYWJsZSk7CiAgICBlbHNlCglndWkuTWFjT1NIYXZlQ250eE1lbnUgPSBmYWxzZTsKCiAgICBpZiAoZ3VpLk1hY09TSGF2ZUNudHhNZW51KQoJZ3VpLk1hY09TSGF2ZUNudHhNZW51ID0gKEluaXRDb250ZXh0dWFsTWVudXMoKT09bm9FcnIpOwoKICAgIHBvbW1lID0gTmV3TWVudSgyNTYsICJccFwwMjQiKTsgLyogMHgxND0gPSBBcHBsZSBNZW51ICovCgogICAgQXBwZW5kTWVudShwb21tZSwgIlxwQWJvdXQgVklNIik7CgogICAgSW5zZXJ0TWVudShwb21tZSwgMCk7CgogICAgRHJhd01lbnVCYXIoKTsKCgojaWZuZGVmIFVTRV9PRkZTRVRFRF9XSU5ET1cKICAgIFNldFJlY3QoJndpbmRSZWN0LCAxMCwgNDgsIDEwKzgwKjcgKyAxNiwgNDgrMjQqMTEpOwojZWxzZQogICAgU2V0UmVjdCgmd2luZFJlY3QsIDMwMCwgNDAsIDMwMCs4MCo3ICsgMTYsIDQwKzI0KjExKTsKI2VuZGlmCgogICAgZ3VpLlZpbVdpbmRvdyA9IE5ld0NXaW5kb3cobmlsLCAmd2luZFJlY3QsICJccGdWaW0gb24gTWFjaW50b3NoIiwgdHJ1ZSwKCQkJem9vbURvY1Byb2MsCgkJCShXaW5kb3dQdHIpLTFMLCB0cnVlLCAwKTsKICAgIEluc3RhbGxSZWNlaXZlSGFuZGxlcigoRHJhZ1JlY2VpdmVIYW5kbGVyVVBQKXJlY2VpdmVIYW5kbGVyLAoJICAgIGd1aS5WaW1XaW5kb3csIE5VTEwpOwogICAgU2V0UG9ydFdpbmRvd1BvcnQoZ3VpLlZpbVdpbmRvdyk7CgogICAgZ3VpLmNoYXJfd2lkdGggPSA3OwogICAgZ3VpLmNoYXJfaGVpZ2h0ID0gMTE7CiAgICBndWkuY2hhcl9hc2NlbnQgPSA2OwogICAgZ3VpLm51bV9yb3dzID0gMjQ7CiAgICBndWkubnVtX2NvbHMgPSA4MDsKICAgIGd1aS5pbl9mb2N1cyA9IFRSVUU7IC8qIEZvciB0aGUgbW9tZW50IC0+IHN5bi4gb2YgZnJvbnQgYXBwbGljYXRpb24gKi8KCiAgICBnU2Nyb2xsQWN0aW9uID0gTmV3Q29udHJvbEFjdGlvblVQUChndWlfbWFjX3Njcm9sbF9hY3Rpb24pOwogICAgZ1Njcm9sbERyYWcgICA9IE5ld0NvbnRyb2xBY3Rpb25VUFAoZ3VpX21hY19kcmFnX3RodW1iKTsKCiAgICAvKiBJbnN0YWxsIENhcmJvbiBldmVudCBjYWxsYmFja3MuICovCiAgICAodm9pZClJbnN0YWxsRm9udFBhbmVsSGFuZGxlcigpOwoKICAgIGRyYWdSZWN0RW5ibCA9IEZBTFNFOwogICAgZHJhZ1JnbiA9IE5VTEw7CiAgICBkcmFnUmVjdENvbnRyb2wgPSBrQ3JlYXRlRW1wdHk7CiAgICBjdXJzb3JSZ24gPSBOZXdSZ24oKTsKI2VuZGlmCiAgICAvKiBEaXNwbGF5IGFueSBwZW5kaW5nIGVycm9yIG1lc3NhZ2VzICovCiAgICBkaXNwbGF5X2Vycm9ycygpOwoKICAgIC8qIEdldCBiYWNrZ3JvdW5kL2ZvcmVncm91bmQgY29sb3JzIGZyb20gc3lzdGVtICovCiAgICAvKiBUT0RPOiBkbyB0aGUgYXBwcm9yaWF0ZSBjYWxsIHRvIGdldCByZWFsIGRlZmF1bHRzICovCiAgICBndWkubm9ybV9waXhlbCA9IDB4MDAwMDAwMDA7CiAgICBndWkuYmFja19waXhlbCA9IDB4MDBGRkZGRkY7CgogICAgLyogR2V0IHRoZSBjb2xvcnMgZnJvbSB0aGUgIk5vcm1hbCIgZ3JvdXAgKHNldCBpbiBzeW50YXguYyBvciBpbiBhIHZpbXJjCiAgICAgKiBmaWxlKS4gKi8KICAgIHNldF9ub3JtYWxfY29sb3JzKCk7CgogICAgLyoKICAgICAqIENoZWNrIHRoYXQgbm9uZSBvZiB0aGUgY29sb3JzIGFyZSB0aGUgc2FtZSBhcyB0aGUgYmFja2dyb3VuZCBjb2xvci4KICAgICAqIFRoZW4gc3RvcmUgdGhlIGN1cnJlbnQgdmFsdWVzIGFzIHRoZSBkZWZhdWx0cy4KICAgICAqLwogICAgZ3VpX2NoZWNrX2NvbG9ycygpOwogICAgZ3VpLmRlZl9ub3JtX3BpeGVsID0gZ3VpLm5vcm1fcGl4ZWw7CiAgICBndWkuZGVmX2JhY2tfcGl4ZWwgPSBndWkuYmFja19waXhlbDsKCiAgICAvKiBHZXQgdGhlIGNvbG9ycyBmb3IgdGhlIGhpZ2hsaWdodCBncm91cHMgKGd1aV9jaGVja19jb2xvcnMoKSBtaWdodCBoYXZlCiAgICAgKiBjaGFuZ2VkIHRoZW0pICovCiAgICBoaWdobGlnaHRfZ3VpX3N0YXJ0ZWQoKTsKCiAgICAvKgogICAgICogU2V0dGluZyB0aGUgZ3VpIGNvbnN0YW50cwogICAgICovCiNpZmRlZiBGRUFUX01FTlUKICAgIGd1aS5tZW51X2hlaWdodCA9IDA7CiNlbmRpZgogICAgZ3VpLnNjcm9sbGJhcl9oZWlnaHQgPSBndWkuc2Nyb2xsYmFyX3dpZHRoID0gMTU7IC8qIGNoZWF0IDEgb3ZlcmxhcCAqLwogICAgZ3VpLmJvcmRlcl9vZmZzZXQgPSBndWkuYm9yZGVyX3dpZHRoID0gMjsKCiAgICAvKiBJZiBRdWFydHotc3R5bGUgdGV4dCBhbnRpYWxpYXNpbmcgaXMgYXZhaWxhYmxlIChzZWUKICAgICAgIGd1aV9tY2hfZHJhd19zdHJpbmcoKSBiZWxvdyksIGVuYWJsZSBpdCBmb3IgYWxsIGZvbnQgc2l6ZXMuICovCiAgICB2aW1fc2V0ZW52KChjaGFyX3UgKikiUURURVhUX01JTlNJWkUiLCAoY2hhcl91ICopIjEiKTsKCiAgICBldmVudFR5cGVTcGVjLmV2ZW50Q2xhc3MgPSBrRXZlbnRDbGFzc01vdXNlOwogICAgZXZlbnRUeXBlU3BlYy5ldmVudEtpbmQgPSBrRXZlbnRNb3VzZVdoZWVsTW92ZWQ7CiAgICBtb3VzZVdoZWVsSGFuZGxlclVQUCA9IE5ld0V2ZW50SGFuZGxlclVQUChndWlfbWFjX21vdXNlX3doZWVsKTsKICAgIGlmIChub0VyciAhPSBJbnN0YWxsQXBwbGljYXRpb25FdmVudEhhbmRsZXIobW91c2VXaGVlbEhhbmRsZXJVUFAsIDEsCgkJCQkgJmV2ZW50VHlwZVNwZWMsIE5VTEwsICZtb3VzZVdoZWVsSGFuZGxlclJlZikpCiAgICB7Cgltb3VzZVdoZWVsSGFuZGxlclJlZiA9IE5VTEw7CglEaXNwb3NlRXZlbnRIYW5kbGVyVVBQKG1vdXNlV2hlZWxIYW5kbGVyVVBQKTsKCW1vdXNlV2hlZWxIYW5kbGVyVVBQID0gTlVMTDsKICAgIH0KCiNpZmRlZiBVU0VfQ0FSQk9OS0VZSEFORExFUgogICAgZXZlbnRUeXBlU3BlYy5ldmVudENsYXNzID0ga0V2ZW50Q2xhc3NUZXh0SW5wdXQ7CiAgICBldmVudFR5cGVTcGVjLmV2ZW50S2luZCA9IGtFdmVudFVuaWNvZGVGb3JLZXlFdmVudDsKICAgIGtleUV2ZW50SGFuZGxlclVQUCA9IE5ld0V2ZW50SGFuZGxlclVQUChndWlfbWFjX2RvS2V5RXZlbnRDYXJib24pOwogICAgaWYgKG5vRXJyICE9IEluc3RhbGxBcHBsaWNhdGlvbkV2ZW50SGFuZGxlcihrZXlFdmVudEhhbmRsZXJVUFAsIDEsCgkJJmV2ZW50VHlwZVNwZWMsIE5VTEwsICZrZXlFdmVudEhhbmRsZXJSZWYpKQogICAgewoJa2V5RXZlbnRIYW5kbGVyUmVmID0gTlVMTDsKCURpc3Bvc2VFdmVudEhhbmRsZXJVUFAoa2V5RXZlbnRIYW5kbGVyVVBQKTsKCWtleUV2ZW50SGFuZGxlclVQUCA9IE5VTEw7CiAgICB9CiNlbmRpZgoKLyoKI2lmZGVmIEZFQVRfTUJZVEUKICAgIHNldF9vcHRpb25fdmFsdWUoKGNoYXJfdSAqKSJlbmNvZGluZyIsIDBMLCAoY2hhcl91ICopInV0Zi04IiwgMCk7CiNlbmRpZgoqLwoKICAgIC8qIFRPRE86IExvYWQgYml0bWFwIGlmIHVzaW5nIFRPT0xCQVIgKi8KICAgIHJldHVybiBPSzsKfQoKLyoKICogQ2FsbGVkIHdoZW4gdGhlIGZvcmVncm91bmQgb3IgYmFja2dyb3VuZCBjb2xvciBoYXMgYmVlbiBjaGFuZ2VkLgogKi8KICAgIHZvaWQKZ3VpX21jaF9uZXdfY29sb3JzKHZvaWQpCnsKICAgIC8qIFRPRE86CiAgICAgKiBUaGlzIHByb2MgaXMgY2FsbGVkIHdoZW4gTm9ybWFsIGlzIHNldCB0byBhIHZhbHVlCiAgICAgKiBzbyB3aGF0IG1zdXQgYmUgZG9uZT8gSSBkb24ndCBrbm93CiAgICAgKi8KfQoKLyoKICogT3BlbiB0aGUgR1VJIHdpbmRvdyB3aGljaCB3YXMgY3JlYXRlZCBieSBhIGNhbGwgdG8gZ3VpX21jaF9pbml0KCkuCiAqLwogICAgaW50Cmd1aV9tY2hfb3Blbih2b2lkKQp7CiAgICBTaG93V2luZG93KGd1aS5WaW1XaW5kb3cpOwoKICAgIGlmIChndWlfd2luX3ggIT0gLTEgJiYgZ3VpX3dpbl95ICE9IC0xKQoJZ3VpX21jaF9zZXRfd2lucG9zKGd1aV93aW5feCwgZ3VpX3dpbl95KTsKCiAgICAvKgogICAgICogTWFrZSB0aGUgR1VJIHRoZSBmb3JlZ3JvdW5kIHByb2Nlc3MgKGluIGNhc2UgaXQgd2FzIGxhdW5jaGVkCiAgICAgKiBmcm9tIHRoZSBUZXJtaW5hbCBvciB2aWEgOmd1aSkuCiAgICAgKi8KICAgIHsKCVByb2Nlc3NTZXJpYWxOdW1iZXIgcHNuOwoJaWYgKEdldEN1cnJlbnRQcm9jZXNzKCZwc24pID09IG5vRXJyKQoJICAgIFNldEZyb250UHJvY2VzcygmcHNuKTsKICAgIH0KCiAgICByZXR1cm4gT0s7Cn0KCiAgICB2b2lkCmd1aV9tY2hfZXhpdChpbnQgcmMpCnsKICAgIC8qIFRPRE86IGZpbmQgb3V0IGFsbCB3aGF0IGlzIG1pc3NpbmcgaGVyZT8gKi8KICAgIERpc3Bvc2VSZ24oY3Vyc29yUmduKTsKCiNpZmRlZiBVU0VfQ0FSQk9OS0VZSEFORExFUgogICAgaWYgKGtleUV2ZW50SGFuZGxlclVQUCkKCURpc3Bvc2VFdmVudEhhbmRsZXJVUFAoa2V5RXZlbnRIYW5kbGVyVVBQKTsKI2VuZGlmCgogICAgaWYgKG1vdXNlV2hlZWxIYW5kbGVyVVBQICE9IE5VTEwpCglEaXNwb3NlRXZlbnRIYW5kbGVyVVBQKG1vdXNlV2hlZWxIYW5kbGVyVVBQKTsKCiNpZmRlZiBVU0VfQVRTVUlfRFJBV0lORwogICAgaWYgKHBfbWFjYXRzdWkgJiYgZ0ZvbnRTdHlsZSkKCUFUU1VEaXNwb3NlU3R5bGUoZ0ZvbnRTdHlsZSk7CiNlbmRpZgoKICAgIC8qIEV4aXQgdG8gc2hlbGw/ICovCiAgICBleGl0KHJjKTsKfQoKLyoKICogR2V0IHRoZSBwb3NpdGlvbiBvZiB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3cuCiAqLwogICAgaW50Cmd1aV9tY2hfZ2V0X3dpbnBvcyhpbnQgKngsIGludCAqeSkKewogICAgLyogVE9ETyAqLwogICAgUmVjdAlib3VuZHM7CiAgICBPU1N0YXR1cwlzdGF0dXM7CgogICAgLyogQ2FyYm9uID49IDEuMC4yLCBNYWNPUyA+PSA4LjUgKi8KICAgIHN0YXR1cyA9IEdldFdpbmRvd0JvdW5kcyhndWkuVmltV2luZG93LCBrV2luZG93U3RydWN0dXJlUmduLCAmYm91bmRzKTsKCiAgICBpZiAoc3RhdHVzICE9IG5vRXJyKQoJcmV0dXJuIEZBSUw7CiAgICAqeCA9IGJvdW5kcy5sZWZ0OwogICAgKnkgPSBib3VuZHMudG9wOwogICAgcmV0dXJuIE9LOwogICAgcmV0dXJuIEZBSUw7Cn0KCi8qCiAqIFNldCB0aGUgcG9zaXRpb24gb2YgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgd2luZG93IHRvIHRoZSBnaXZlbgogKiBjb29yZGluYXRlcy4KICovCiAgICB2b2lkCmd1aV9tY2hfc2V0X3dpbnBvcyhpbnQgeCwgaW50IHkpCnsKICAgIC8qIFRPRE86ICBTaG91bGQgbWFrZSBzdXJlIHRoZSB3aW5kb3cgaXMgbW92ZSB3aXRoaW4gcmFuZ2UKICAgICAqCSAgICAgIGUuZy46IHkgPiB+MTYgW01lbnUgYmFyXSwgeCA+IDAsIHggPCBzY3JlZW4gd2lkdGgKICAgICAqLwogICAgTW92ZVdpbmRvdyhndWkuVmltV2luZG93LCB4LCB5LCBUUlVFKTsKfQoKICAgIHZvaWQKZ3VpX21jaF9zZXRfc2hlbGxzaXplKAogICAgaW50CQl3aWR0aCwKICAgIGludAkJaGVpZ2h0LAogICAgaW50CQltaW5fd2lkdGgsCiAgICBpbnQJCW1pbl9oZWlnaHQsCiAgICBpbnQJCWJhc2Vfd2lkdGgsCiAgICBpbnQJCWJhc2VfaGVpZ2h0LAogICAgaW50CQlkaXJlY3Rpb24pCnsKICAgIENHcmFmUHRyCVZpbVBvcnQ7CiAgICBSZWN0CVZpbUJvdW5kOwoKICAgIGlmIChndWkud2hpY2hfc2Nyb2xsYmFyc1tTQkFSX0xFRlRdKQogICAgewoJVmltUG9ydCA9IEdldFdpbmRvd1BvcnQoZ3VpLlZpbVdpbmRvdyk7CglHZXRQb3J0Qm91bmRzKFZpbVBvcnQsICZWaW1Cb3VuZCk7CglWaW1Cb3VuZC5sZWZ0ID0gLWd1aS5zY3JvbGxiYXJfd2lkdGg7IC8qICsgMTsqLwoJU2V0UG9ydEJvdW5kcyhWaW1Qb3J0LCAmVmltQm91bmQpOwogICAgLyoJR2V0V2luZG93Qm91bmRzKGd1aS5WaW1XaW5kb3csIGtXaW5kb3dHbG9iYWxQb3J0UmduLCAmd2luUG9ydFJlY3QpOyA/PyovCiAgICB9CiAgICBlbHNlCiAgICB7CglWaW1Qb3J0ID0gR2V0V2luZG93UG9ydChndWkuVmltV2luZG93KTsKCUdldFBvcnRCb3VuZHMoVmltUG9ydCwgJlZpbUJvdW5kKTsKCVZpbUJvdW5kLmxlZnQgPSAwOwoJU2V0UG9ydEJvdW5kcyhWaW1Qb3J0LCAmVmltQm91bmQpOwogICAgfQoKICAgIFNpemVXaW5kb3coZ3VpLlZpbVdpbmRvdywgd2lkdGgsIGhlaWdodCwgVFJVRSk7CgogICAgZ3VpX3Jlc2l6ZV9zaGVsbCh3aWR0aCwgaGVpZ2h0KTsKfQoKLyoKICogR2V0IHRoZSBzY3JlZW4gZGltZW5zaW9ucy4KICogQWxsb3cgMTAgcGl4ZWxzIGZvciBob3Jpem9udGFsIGJvcmRlcnMsIDQwIGZvciB2ZXJ0aWNhbCBib3JkZXJzLgogKiBJcyB0aGVyZSBubyB3YXkgdG8gZmluZCBvdXQgaG93IHdpZGUgdGhlIGJvcmRlcnMgcmVhbGx5IGFyZT8KICogVE9ETzogQWRkIGxpdmUgdWRhdGUgb2YgdGhvc2UgdmFsdWUgb24gc3VzcGVuZC9yZXN1bWUuCiAqLwogICAgdm9pZApndWlfbWNoX2dldF9zY3JlZW5fZGltZW5zaW9ucyhpbnQgKnNjcmVlbl93LCBpbnQgKnNjcmVlbl9oKQp7CiAgICBHREhhbmRsZQlkb21pbmFudERldmljZSA9IEdldE1haW5EZXZpY2UoKTsKICAgIFJlY3QJc2NyZWVuUmVjdCA9ICgqKmRvbWluYW50RGV2aWNlKS5nZFJlY3Q7CgogICAgKnNjcmVlbl93ID0gc2NyZWVuUmVjdC5yaWdodCAtIDEwOwogICAgKnNjcmVlbl9oID0gc2NyZWVuUmVjdC5ib3R0b20gLSA0MDsKfQoKCi8qCiAqIE9wZW4gdGhlIEZvbnQgUGFuZWwgYW5kIHdhaXQgZm9yIHRoZSB1c2VyIHRvIHNlbGVjdCBhIGZvbnQgYW5kCiAqIGNsb3NlIHRoZSBwYW5lbC4gIFRoZW4gZmlsbCB0aGUgYnVmZmVyIHBvaW50ZWQgdG8gYnkgZm9udF9uYW1lIHdpdGgKICogdGhlIG5hbWUgYW5kIHNpemUgb2YgdGhlIHNlbGVjdGVkIGZvbnQgYW5kIHJldHVybiB0aGUgZm9udCdzIGhhbmRsZSwKICogb3IgTk9GT05UIGluIGNhc2Ugb2YgYW4gZXJyb3IuCiAqLwogICAgc3RhdGljIEd1aUZvbnQKZ3VpX21hY19zZWxlY3RfZm9udChjaGFyX3UgKmZvbnRfbmFtZSkKewogICAgR3VpRm9udAkJICAgIHNlbGVjdGVkX2ZvbnQgPSBOT0ZPTlQ7CiAgICBPU1N0YXR1cwkJICAgIHN0YXR1czsKICAgIEZvbnRTZWxlY3Rpb25RRFN0eWxlICAgIGN1cnJfZm9udDsKCiAgICAvKiBJbml0aWFsaXplIHRoZSBGb250IFBhbmVsIHdpdGggdGhlIGN1cnJlbnQgZm9udC4gKi8KICAgIGN1cnJfZm9udC5pbnN0YW5jZS5mb250RmFtaWx5ID0gZ3VpLm5vcm1fZm9udCAmIDB4RkZGRjsKICAgIGN1cnJfZm9udC5zaXplID0gKGd1aS5ub3JtX2ZvbnQgPj4gMTYpOwogICAgLyogVE9ETzogc2V0IGZvbnRTdHlsZSBvbmNlIHN0eWxlcyBhcmUgc3VwcG9ydGVkIGluIGd1aV9tYWNfZmluZF9mb250KCkgKi8KICAgIGN1cnJfZm9udC5pbnN0YW5jZS5mb250U3R5bGUgPSAwOwogICAgY3Vycl9mb250Lmhhc0NvbG9yID0gZmFsc2U7CiAgICBjdXJyX2ZvbnQudmVyc2lvbiA9IDA7IC8qIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBzdHlsZSBzdHJ1Y3R1cmUgKi8KICAgIHN0YXR1cyA9IFNldEZvbnRJbmZvRm9yU2VsZWN0aW9uKGtGb250U2VsZWN0aW9uUURUeXBlLAoJICAgIC8qbnVtU3R5bGVzPSovMSwgJmN1cnJfZm9udCwgLypldmVudFRhcmdldD0qL05VTEwpOwoKICAgIGdGb250UGFuZWxJbmZvLmZhbWlseSA9IGN1cnJfZm9udC5pbnN0YW5jZS5mb250RmFtaWx5OwogICAgZ0ZvbnRQYW5lbEluZm8uc3R5bGUgPSBjdXJyX2ZvbnQuaW5zdGFuY2UuZm9udFN0eWxlOwogICAgZ0ZvbnRQYW5lbEluZm8uc2l6ZSA9IGN1cnJfZm9udC5zaXplOwoKICAgIC8qIFBvcCB1cCB0aGUgRm9udCBQYW5lbC4gKi8KICAgIHN0YXR1cyA9IEZQU2hvd0hpZGVGb250UGFuZWwoKTsKICAgIGlmIChzdGF0dXMgPT0gbm9FcnIpCiAgICB7CgkvKgoJICogVGhlIEZvbnQgUGFuZWwgaXMgbW9kZWxlc3MuICBXZSByZWFsbHkgbmVlZCBpdCB0byBiZSBtb2RhbCwKCSAqIHNvIHdlIHNwaW4gaW4gYW4gZXZlbnQgbG9vcCB1bnRpbCB0aGUgcGFuZWwgaXMgY2xvc2VkLgoJICovCglnRm9udFBhbmVsSW5mby5pc1BhbmVsVmlzaWJsZSA9IHRydWU7Cgl3aGlsZSAoZ0ZvbnRQYW5lbEluZm8uaXNQYW5lbFZpc2libGUpCgl7CgkgICAgRXZlbnRSZWNvcmQgZTsKCSAgICBXYWl0TmV4dEV2ZW50KGV2ZXJ5RXZlbnQsICZlLCAvKnNsZWVwPSovMjAsIC8qbW91c2VSZ249Ki9OVUxMKTsKCX0KCglHZXRGb250UGFuZWxTZWxlY3Rpb24oZm9udF9uYW1lKTsKCXNlbGVjdGVkX2ZvbnQgPSBndWlfbWFjX2ZpbmRfZm9udChmb250X25hbWUpOwogICAgfQogICAgcmV0dXJuIHNlbGVjdGVkX2ZvbnQ7Cn0KCgovKgogKiBJbml0aWFsaXNlIHZpbSB0byB1c2UgdGhlIGZvbnQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4JUmV0dXJuIEZBSUwgaWYgdGhlIGZvbnQKICogY291bGQgbm90IGJlIGxvYWRlZCwgT0sgb3RoZXJ3aXNlLgogKi8KICAgIGludApndWlfbWNoX2luaXRfZm9udChjaGFyX3UgKmZvbnRfbmFtZSwgaW50IGZvbnRzZXQpCnsKICAgIC8qIFRPRE86IEFkZCBzdXBwb3J0IGZvciBib2xkIGl0YWxpYyB1bmRlcmxpbmUgcHJvcG9ydGlvbmFsIGV0Yy4uLiAqLwogICAgU3RyMjU1CXN1Z2dlc3RlZEZvbnQgPSAiXHBNb25hY28iOwogICAgaW50CQlzdWdnZXN0ZWRTaXplID0gMTA7CiAgICBGb250SW5mbwlmb250X2luZm87CiAgICBzaG9ydAlmb250X2lkOwogICAgR3VpRm9udAlmb250OwogICAgY2hhcl91CXVzZWRfZm9udF9uYW1lWzUxMl07CgojaWZkZWYgVVNFX0FUU1VJX0RSQVdJTkcKICAgIGlmIChwX21hY2F0c3VpICYmIGdGb250U3R5bGUgPT0gTlVMTCkKICAgIHsKCWlmIChBVFNVQ3JlYXRlU3R5bGUoJmdGb250U3R5bGUpICE9IG5vRXJyKQoJICAgIGdGb250U3R5bGUgPSBOVUxMOwogICAgfQojZW5kaWYKCiAgICBpZiAoZm9udF9uYW1lID09IE5VTEwpCiAgICB7CgkvKiBGaXJzdCB0cnkgdG8gZ2V0IHRoZSBzdWdnZXN0ZWQgZm9udCAqLwoJR2V0Rk51bShzdWdnZXN0ZWRGb250LCAmZm9udF9pZCk7CgoJaWYgKGZvbnRfaWQgPT0gMCkKCXsKCSAgICAvKiBUaGVuIHBpY2t1cCB0aGUgc3RhbmRhcmQgYXBwbGljYXRpb24gZm9udCAqLwoJICAgIGZvbnRfaWQgPSBHZXRBcHBGb250KCk7CgkgICAgU1RSQ1BZKHVzZWRfZm9udF9uYW1lLCAiZGVmYXVsdCIpOwoJfQoJZWxzZQoJICAgIFNUUkNQWSh1c2VkX2ZvbnRfbmFtZSwgIk1vbmFjbyIpOwoJZm9udCA9IChzdWdnZXN0ZWRTaXplIDw8IDE2KSArICgobG9uZykgZm9udF9pZCAmIDB4RkZGRik7CiAgICB9CiAgICBlbHNlIGlmIChTVFJDTVAoZm9udF9uYW1lLCAiKiIpID09IDApCiAgICB7CgljaGFyX3UgKm5ld19wX2d1aWZvbnQ7CgoJZm9udCA9IGd1aV9tYWNfc2VsZWN0X2ZvbnQodXNlZF9mb250X25hbWUpOwoJaWYgKGZvbnQgPT0gTk9GT05UKQoJICAgIHJldHVybiBGQUlMOwoKCS8qIFNldCBndWlmb250IHRvIHRoZSBuYW1lIG9mIHRoZSBzZWxlY3RlZCBmb250LiAqLwoJbmV3X3BfZ3VpZm9udCA9IGFsbG9jKFNUUkxFTih1c2VkX2ZvbnRfbmFtZSkgKyAxKTsKCWlmIChuZXdfcF9ndWlmb250ICE9IE5VTEwpCgl7CgkgICAgU1RSQ1BZKG5ld19wX2d1aWZvbnQsIHVzZWRfZm9udF9uYW1lKTsKCSAgICB2aW1fZnJlZShwX2d1aWZvbnQpOwoJICAgIHBfZ3VpZm9udCA9IG5ld19wX2d1aWZvbnQ7CgkgICAgLyogUmVwbGFjZSBzcGFjZXMgaW4gdGhlIGZvbnQgbmFtZSB3aXRoIHVuZGVyc2NvcmVzLiAqLwoJICAgIGZvciAoIDsgKm5ld19wX2d1aWZvbnQ7ICsrbmV3X3BfZ3VpZm9udCkKCSAgICB7CgkJaWYgKCpuZXdfcF9ndWlmb250ID09ICcgJykKCQkgICAgKm5ld19wX2d1aWZvbnQgPSAnXyc7CgkgICAgfQoJfQogICAgfQogICAgZWxzZQogICAgewoJZm9udCA9IGd1aV9tYWNfZmluZF9mb250KGZvbnRfbmFtZSk7Cgl2aW1fc3RybmNweSh1c2VkX2ZvbnRfbmFtZSwgZm9udF9uYW1lLCBzaXplb2YodXNlZF9mb250X25hbWUpIC0gMSk7CgoJaWYgKGZvbnQgPT0gTk9GT05UKQoJICAgIHJldHVybiBGQUlMOwogICAgfQoKICAgIGd1aS5ub3JtX2ZvbnQgPSBmb250OwoKICAgIGhsX3NldF9mb250X25hbWUodXNlZF9mb250X25hbWUpOwoKICAgIFRleHRTaXplKGZvbnQgPj4gMTYpOwogICAgVGV4dEZvbnQoZm9udCAmIDB4RkZGRik7CgogICAgR2V0Rm9udEluZm8oJmZvbnRfaW5mbyk7CgogICAgZ3VpLmNoYXJfYXNjZW50ID0gZm9udF9pbmZvLmFzY2VudDsKICAgIGd1aS5jaGFyX3dpZHRoICA9IENoYXJXaWR0aCgnXycpOwogICAgZ3VpLmNoYXJfaGVpZ2h0ID0gZm9udF9pbmZvLmFzY2VudCArIGZvbnRfaW5mby5kZXNjZW50ICsgcF9saW5lc3BhY2U7CgojaWZkZWYgVVNFX0FUU1VJX0RSQVdJTkcKICAgIEFUU1VGb250SUQJCQlmb250SUQ7CiAgICBGaXhlZAkJCWZvbnRTaXplOwogICAgQVRTU3R5bGVSZW5kZXJpbmdPcHRpb25zCWZvbnRPcHRpb25zOwoKICAgIGlmIChwX21hY2F0c3VpICYmIGdGb250U3R5bGUpCiAgICB7Cglmb250SUQgPSBmb250ICYgMHhGRkZGOwoJZm9udFNpemUgPSBMb25nMkZpeChmb250ID4+IDE2KTsKCgkvKiBObyBhbnRpYWxpYXNpbmcgYnkgZGVmYXVsdCAoZG8gbm90IGF0dGVtcHQgdG8gdG91Y2ggYW50aWFsaXNpbmcKCSAqIG9wdGlvbnMgb24gcHJlLUphZ3VhcikgKi8KCWZvbnRPcHRpb25zID0KCSAgICAoZ01hY1N5c3RlbVZlcnNpb24gPj0gMHgxMDIwKSA/CgkgICAga0FUU1N0eWxlTm9BbnRpQWxpYXNpbmcgOgoJICAgIGtBVFNTdHlsZU5vT3B0aW9uczsKCglBVFNVQXR0cmlidXRlVGFnIGF0dHJpYlRhZ3NbXSA9Cgl7CgkgICAga0FUU1VGb250VGFnLCBrQVRTVVNpemVUYWcsIGtBVFNVU3R5bGVSZW5kZXJpbmdPcHRpb25zVGFnLAoJICAgIGtBVFNVTWF4QVRTVUlUYWdWYWx1ZSsxCgl9OwoJQnl0ZUNvdW50IGF0dHJpYlNpemVzW10gPQoJewoJICAgIHNpemVvZihBVFNVRm9udElEKSwgc2l6ZW9mKEZpeGVkKSwKCSAgICBzaXplb2YoQVRTU3R5bGVSZW5kZXJpbmdPcHRpb25zKSwgc2l6ZW9mIGZvbnQKCX07CglBVFNVQXR0cmlidXRlVmFsdWVQdHIgYXR0cmliVmFsdWVzW10gPQoJewoJICAgICZmb250SUQsICZmb250U2l6ZSwgJmZvbnRPcHRpb25zLCAmZm9udAoJfTsKCgkvKiBDb252ZXJ0IGZvbnQgaWQgdG8gQVRTVUZvbnRJRCAqLwoJaWYgKEZNR2V0Rm9udEZyb21Gb250RmFtaWx5SW5zdGFuY2UoZm9udElELCAwLCAmZm9udElELCBOVUxMKSA9PSBub0VycikKCXsKCSAgICBpZiAoQVRTVVNldEF0dHJpYnV0ZXMoZ0ZvbnRTdHlsZSwKCQkJKHNpemVvZiBhdHRyaWJUYWdzKS9zaXplb2YoQVRTVUF0dHJpYnV0ZVRhZyksCgkJCWF0dHJpYlRhZ3MsIGF0dHJpYlNpemVzLCBhdHRyaWJWYWx1ZXMpICE9IG5vRXJyKQoJICAgIHsKCQlBVFNVRGlzcG9zZVN0eWxlKGdGb250U3R5bGUpOwoJCWdGb250U3R5bGUgPSBOVUxMOwoJICAgIH0KCX0KICAgIH0KI2VuZGlmCgogICAgcmV0dXJuIE9LOwp9CgovKgogKiBBZGp1c3QgZ3VpLmNoYXJfaGVpZ2h0IChhZnRlciAnbGluZXNwYWNlJyB3YXMgY2hhbmdlZCkuCiAqLwogICAgaW50Cmd1aV9tY2hfYWRqdXN0X2NoYXJoZWlnaHQodm9pZCkKewogICAgRm9udEluZm8gICAgZm9udF9pbmZvOwoKICAgIEdldEZvbnRJbmZvKCZmb250X2luZm8pOwogICAgZ3VpLmNoYXJfaGVpZ2h0ID0gZm9udF9pbmZvLmFzY2VudCArIGZvbnRfaW5mby5kZXNjZW50ICsgcF9saW5lc3BhY2U7CiAgICBndWkuY2hhcl9hc2NlbnQgPSBmb250X2luZm8uYXNjZW50ICsgcF9saW5lc3BhY2UgLyAyOwogICAgcmV0dXJuIE9LOwp9CgovKgogKiBHZXQgYSBmb250IHN0cnVjdHVyZSBmb3IgaGlnaGxpZ2h0aW5nLgogKi8KICAgIEd1aUZvbnQKZ3VpX21jaF9nZXRfZm9udChjaGFyX3UgKm5hbWUsIGludCBnaXZlRXJyb3JJZk1pc3NpbmcpCnsKICAgIEd1aUZvbnQgZm9udDsKCiAgICBmb250ID0gZ3VpX21hY19maW5kX2ZvbnQobmFtZSk7CgogICAgaWYgKGZvbnQgPT0gTk9GT05UKQogICAgewoJaWYgKGdpdmVFcnJvcklmTWlzc2luZykKCSAgICBFTVNHMihfKGVfZm9udCksIG5hbWUpOwoJcmV0dXJuIE5PRk9OVDsKICAgIH0KICAgIC8qCiAgICAgKiBUT0RPIDogQWNjZXB0IG9ubHkgbW9ub3NwYWNlCiAgICAgKi8KCiAgICByZXR1cm4gZm9udDsKfQoKI2lmIGRlZmluZWQoRkVBVF9FVkFMKSB8fCBkZWZpbmVkKFBST1RPKQovKgogKiBSZXR1cm4gdGhlIG5hbWUgb2YgZm9udCAiZm9udCIgaW4gYWxsb2NhdGVkIG1lbW9yeS4KICogRG9uJ3Qga25vdyBob3cgdG8gZ2V0IHRoZSBhY3R1YWwgbmFtZSwgdGh1cyB1c2UgdGhlIHByb3ZpZGVkIG5hbWUuCiAqLwogICAgY2hhcl91ICoKZ3VpX21jaF9nZXRfZm9udG5hbWUoR3VpRm9udCBmb250LCBjaGFyX3UgKm5hbWUpCnsKICAgIGlmIChuYW1lID09IE5VTEwpCglyZXR1cm4gTlVMTDsKICAgIHJldHVybiB2aW1fc3Ryc2F2ZShuYW1lKTsKfQojZW5kaWYKCi8qCiAqIFNldCB0aGUgY3VycmVudCB0ZXh0IGZvbnQuCiAqLwogICAgdm9pZApndWlfbWNoX3NldF9mb250KEd1aUZvbnQgZm9udCkKewojaWZkZWYgVVNFX0FUU1VJX0RSQVdJTkcKICAgIEd1aUZvbnQJCQljdXJyRm9udDsKICAgIEJ5dGVDb3VudAkJCWFjdHVhbEZvbnRCeXRlQ291bnQ7CiAgICBBVFNVRm9udElECQkJZm9udElEOwogICAgRml4ZWQJCQlmb250U2l6ZTsKICAgIEFUU1N0eWxlUmVuZGVyaW5nT3B0aW9ucwlmb250T3B0aW9uczsKCiAgICBpZiAocF9tYWNhdHN1aSAmJiBnRm9udFN0eWxlKQogICAgewoJLyogQXZvaWQgc2V0dGluZyBzYW1lIGZvbnQgYWdhaW4gKi8KCWlmIChBVFNVR2V0QXR0cmlidXRlKGdGb250U3R5bGUsIGtBVFNVTWF4QVRTVUlUYWdWYWx1ZSsxLCBzaXplb2YgZm9udCwKCQkgICAgJmN1cnJGb250LCAmYWN0dWFsRm9udEJ5dGVDb3VudCkgPT0gbm9FcnIgJiYKCQlhY3R1YWxGb250Qnl0ZUNvdW50ID09IChzaXplb2YgZm9udCkpCgl7CgkgICAgaWYgKGN1cnJGb250ID09IGZvbnQpCgkJcmV0dXJuOwoJfQoKCWZvbnRJRCA9IGZvbnQgJiAweEZGRkY7Cglmb250U2l6ZSA9IExvbmcyRml4KGZvbnQgPj4gMTYpOwoJLyogUmVzcGVjdCBwX2FudGlhbGlhcyBzZXR0aW5nIG9ubHkgZm9yIHdpZGUgZm9udC4KCSAqIFRoZSByZWFzb24gZm9yIGRvaW5nIHRoaXMgYXQgdGhlIG1vbWVudCBpcyBhIGJpdCBjb21wbGljYXRlZCwKCSAqIGJ1dCBpdCdzIG1haW5seSBiZWNhdXNlIGEpIGxhdGluIChub24td2lkZSkgYWxpYXNlZCBmb250cwoJICogbG9vayBiYWQgaW4gT1MgWCAxMC4zLnggYW5kIGJlbG93IChkdWUgdG8gYSBidWcgaW4gQVRTKSwgYW5kCgkgKiBiKSB3aWRlIG11bHRpYnl0ZSBpbnB1dCBkb2VzIG5vdCBzdWZmZXIgZnJvbSB0aGF0IHByb2JsZW0uICovCgkvKmZvbnRPcHRpb25zID0KCSAgICAocF9hbnRpYWxpYXMgJiYgKGZvbnQgPT0gZ3VpLndpZGVfZm9udCkpID8KCSAgICBrQVRTU3R5bGVOb09wdGlvbnMgOiBrQVRTU3R5bGVOb0FudGlBbGlhc2luZzsKCSovCgkvKmZvbnRPcHRpb25zID0ga0FUU1N0eWxlQW50aUFsaWFzaW5nOyovCgoJQVRTVUF0dHJpYnV0ZVRhZyBhdHRyaWJUYWdzW10gPQoJewoJICAgIGtBVFNVRm9udFRhZywga0FUU1VTaXplVGFnLCBrQVRTVVN0eWxlUmVuZGVyaW5nT3B0aW9uc1RhZywKCSAgICBrQVRTVU1heEFUU1VJVGFnVmFsdWUrMQoJfTsKCUJ5dGVDb3VudCBhdHRyaWJTaXplc1tdID0KCXsKCSAgICBzaXplb2YoQVRTVUZvbnRJRCksIHNpemVvZihGaXhlZCksCgkgICAgc2l6ZW9mKEFUU1N0eWxlUmVuZGVyaW5nT3B0aW9ucyksIHNpemVvZiBmb250Cgl9OwoJQVRTVUF0dHJpYnV0ZVZhbHVlUHRyIGF0dHJpYlZhbHVlc1tdID0KCXsKCSAgICAmZm9udElELCAmZm9udFNpemUsICZmb250T3B0aW9ucywgJmZvbnQKCX07CgoJaWYgKEZNR2V0Rm9udEZyb21Gb250RmFtaWx5SW5zdGFuY2UoZm9udElELCAwLCAmZm9udElELCBOVUxMKSA9PSBub0VycikKCXsKCSAgICBpZiAoQVRTVVNldEF0dHJpYnV0ZXMoZ0ZvbnRTdHlsZSwKCQkJKHNpemVvZiBhdHRyaWJUYWdzKS9zaXplb2YoQVRTVUF0dHJpYnV0ZVRhZyksCgkJCWF0dHJpYlRhZ3MsIGF0dHJpYlNpemVzLCBhdHRyaWJWYWx1ZXMpICE9IG5vRXJyKQoJICAgIHsKIyBpZm5kZWYgTkRFQlVHCgkJZnByaW50ZihzdGRlcnIsICJjb3VsZG4ndCBzZXQgZm9udCBzdHlsZVxuIik7CiMgZW5kaWYKCQlBVFNVRGlzcG9zZVN0eWxlKGdGb250U3R5bGUpOwoJCWdGb250U3R5bGUgPSBOVUxMOwoJICAgIH0KCX0KCiAgICB9CgogICAgaWYgKHBfbWFjYXRzdWkgJiYgIWdJc0ZvbnRGYWxsYmFja1NldCkKICAgIHsKCS8qIFNldHVwIGF1dG9tYXRpYyBmb250IHN1YnN0aXR1dGlvbi4gVGhlIHVzZXIncyBndWlmb250d2lkZQoJICogaXMgdHJpZWQgZmlyc3QsIHRoZW4gdGhlIHN5c3RlbSB0cmllcyBvdGhlciBmb250cy4gKi8KLyoKCUFUU1VBdHRyaWJ1dGVUYWcgZmFsbGJhY2tUYWdzW10gPSB7IGtBVFNVTGluZUZvbnRGYWxsYmFja3NUYWcgfTsKCUJ5dGVDb3VudCBmYWxsYmFja1NpemVzW10gPSB7IHNpemVvZihBVFNVRm9udEZhbGxiYWNrcykgfTsKCUFUU1VDcmVhdGVGb250RmFsbGJhY2tzKCZnRm9udEZhbGxiYWNrcyk7CglBVFNVU2V0T2JqRm9udEZhbGxiYWNrcyhnRm9udEZhbGxiYWNrcywgKTsKKi8KCWlmIChndWkud2lkZV9mb250KQoJewoJICAgIEFUU1VGb250SUQgZmFsbGJhY2tGb250czsKCSAgICBnSXNGb250RmFsbGJhY2tTZXQgPSBUUlVFOwoKCSAgICBpZiAoRk1HZXRGb250RnJvbUZvbnRGYW1pbHlJbnN0YW5jZSgKCQkJKGd1aS53aWRlX2ZvbnQgJiAweEZGRkYpLAoJCQkwLAoJCQkmZmFsbGJhY2tGb250cywKCQkJTlVMTCkgPT0gbm9FcnIpCgkgICAgewoJCUFUU1VTZXRGb250RmFsbGJhY2tzKChzaXplb2YgZmFsbGJhY2tGb250cykvc2l6ZW9mKEFUU1VGb250SUQpLCAmZmFsbGJhY2tGb250cywga0FUU1VTZXF1ZW50aWFsRmFsbGJhY2tzUHJlZmVycmVkKTsKCSAgICB9Ci8qCglBVFNVQXR0cmlidXRlVmFsdWVQdHIgZmFsbGJhY2tWYWx1ZXNbXSA9IHsgfTsKKi8KCX0KICAgIH0KI2VuZGlmCiAgICBUZXh0U2l6ZShmb250ID4+IDE2KTsKICAgIFRleHRGb250KGZvbnQgJiAweEZGRkYpOwp9CgovKgogKiBJZiBhIGZvbnQgaXMgbm90IGdvaW5nIHRvIGJlIHVzZWQsIGZyZWUgaXRzIHN0cnVjdHVyZS4KICovCiAgICB2b2lkCmd1aV9tY2hfZnJlZV9mb250KGZvbnQpCiAgICBHdWlGb250CWZvbnQ7CnsKICAgIC8qCiAgICAgKiBGcmVlIGZvbnQgd2hlbiAiZm9udCIgaXMgbm90IDAuCiAgICAgKiBOb3RoaW5nIHRvIGRvIGluIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uLCBzaW5jZQogICAgICogbm90aGluZyBpcyBhbGxvY2F0ZWQgZm9yIGVhY2ggZm9udCB1c2VkLgogICAgICovCn0KCiAgICBzdGF0aWMgaW50CmhleF9kaWdpdChpbnQgYykKewogICAgaWYgKGlzZGlnaXQoYykpCglyZXR1cm4gYyAtICcwJzsKICAgIGMgPSBUT0xPV0VSX0FTQyhjKTsKICAgIGlmIChjID49ICdhJyAmJiBjIDw9ICdmJykKCXJldHVybiBjIC0gJ2EnICsgMTA7CiAgICByZXR1cm4gLTEwMDA7Cn0KCi8qCiAqIFJldHVybiB0aGUgUGl4ZWwgdmFsdWUgKGNvbG9yKSBmb3IgdGhlIGdpdmVuIGNvbG9yIG5hbWUuICBUaGlzIHJvdXRpbmUgd2FzCiAqIHByZXR0eSBtdWNoIHRha2VuIGZyb20gZXhhbXBsZSBjb2RlIGluIHRoZSBTaWxpY29uIEdyYXBoaWNzIE9TRi9Nb3RpZgogKiBQcm9ncmFtbWVyJ3MgR3VpZGUuCiAqIFJldHVybiBJTlZBTENPTE9SIHdoZW4gZmFpbGVkLgogKi8KICAgIGd1aWNvbG9yX1QKZ3VpX21jaF9nZXRfY29sb3IoY2hhcl91ICpuYW1lKQp7CiAgICAvKiBUT0RPOiBBZGQgc3VwcG9ydCBmb3IgdGhlIG5ldyBuYW1lZCBjb2xvciBvZiBNYWNPUyA4CiAgICAgKi8KICAgIFJHQkNvbG9yCU1hY0NvbG9yOwovLyAgICBndWljb2xvcl9UCWNvbG9yID0gMDsKCiAgICB0eXBlZGVmIHN0cnVjdCBndWljb2xvcl90VGFibGUKICAgIHsKCWNoYXIJICAgICpuYW1lOwoJZ3VpY29sb3JfVCAgY29sb3I7CiAgICB9IGd1aWNvbG9yX3RUYWJsZTsKCiAgICAvKgogICAgICogVGhlIGNvbW1lbnQgYXQgdGhlIGVuZCBvZiBlYWNoIGxpbmUgaXMgdGhlIHNvdXJjZQogICAgICogKE1hYywgV2luZG93LCBVbml4KSBhbmQgdGhlIG51bWJlciBpcyB0aGUgdW5peCByZ2IudHh0IHZhbHVlCiAgICAgKi8KICAgIHN0YXRpYyBndWljb2xvcl90VGFibGUgdGFibGVbXSA9CiAgICB7Cgl7IkJsYWNrIiwJUkdCKDB4MDAsIDB4MDAsIDB4MDApfSwKCXsiZGFya2dyYXkiLAlSR0IoMHg4MCwgMHg4MCwgMHg4MCl9LCAvKlcqLwoJeyJkYXJrZ3JleSIsCVJHQigweDgwLCAweDgwLCAweDgwKX0sIC8qVyovCgl7IkdyYXkiLAlSR0IoMHhDMCwgMHhDMCwgMHhDMCl9LCAvKlcqLwoJeyJHcmV5IiwJUkdCKDB4QzAsIDB4QzAsIDB4QzApfSwgLypXKi8KCXsibGlnaHRncmF5IiwJUkdCKDB4RTAsIDB4RTAsIDB4RTApfSwgLypXKi8KCXsibGlnaHRncmV5IiwJUkdCKDB4RTAsIDB4RTAsIDB4RTApfSwgLypXKi8KCXsiZ3JheTEwIiwJUkdCKDB4MUEsIDB4MUEsIDB4MUEpfSwgLypXKi8KCXsiZ3JleTEwIiwJUkdCKDB4MUEsIDB4MUEsIDB4MUEpfSwgLypXKi8KCXsiZ3JheTIwIiwJUkdCKDB4MzMsIDB4MzMsIDB4MzMpfSwgLypXKi8KCXsiZ3JleTIwIiwJUkdCKDB4MzMsIDB4MzMsIDB4MzMpfSwgLypXKi8KCXsiZ3JheTMwIiwJUkdCKDB4NEQsIDB4NEQsIDB4NEQpfSwgLypXKi8KCXsiZ3JleTMwIiwJUkdCKDB4NEQsIDB4NEQsIDB4NEQpfSwgLypXKi8KCXsiZ3JheTQwIiwJUkdCKDB4NjYsIDB4NjYsIDB4NjYpfSwgLypXKi8KCXsiZ3JleTQwIiwJUkdCKDB4NjYsIDB4NjYsIDB4NjYpfSwgLypXKi8KCXsiZ3JheTUwIiwJUkdCKDB4N0YsIDB4N0YsIDB4N0YpfSwgLypXKi8KCXsiZ3JleTUwIiwJUkdCKDB4N0YsIDB4N0YsIDB4N0YpfSwgLypXKi8KCXsiZ3JheTYwIiwJUkdCKDB4OTksIDB4OTksIDB4OTkpfSwgLypXKi8KCXsiZ3JleTYwIiwJUkdCKDB4OTksIDB4OTksIDB4OTkpfSwgLypXKi8KCXsiZ3JheTcwIiwJUkdCKDB4QjMsIDB4QjMsIDB4QjMpfSwgLypXKi8KCXsiZ3JleTcwIiwJUkdCKDB4QjMsIDB4QjMsIDB4QjMpfSwgLypXKi8KCXsiZ3JheTgwIiwJUkdCKDB4Q0MsIDB4Q0MsIDB4Q0MpfSwgLypXKi8KCXsiZ3JleTgwIiwJUkdCKDB4Q0MsIDB4Q0MsIDB4Q0MpfSwgLypXKi8KCXsiZ3JheTkwIiwJUkdCKDB4RTUsIDB4RTUsIDB4RTUpfSwgLypXKi8KCXsiZ3JleTkwIiwJUkdCKDB4RTUsIDB4RTUsIDB4RTUpfSwgLypXKi8KCXsid2hpdGUiLAlSR0IoMHhGRiwgMHhGRiwgMHhGRil9LAoJeyJkYXJrcmVkIiwJUkdCKDB4ODAsIDB4MDAsIDB4MDApfSwgLypXKi8KCXsicmVkIiwJCVJHQigweERELCAweDA4LCAweDA2KX0sIC8qTSovCgl7ImxpZ2h0cmVkIiwJUkdCKDB4RkYsIDB4QTAsIDB4QTApfSwgLypXKi8KCXsiRGFya0JsdWUiLAlSR0IoMHgwMCwgMHgwMCwgMHg4MCl9LCAvKlcqLwoJeyJCbHVlIiwJUkdCKDB4MDAsIDB4MDAsIDB4RDQpfSwgLypNKi8KCXsibGlnaHRibHVlIiwJUkdCKDB4QTAsIDB4QTAsIDB4RkYpfSwgLypXKi8KCXsiRGFya0dyZWVuIiwJUkdCKDB4MDAsIDB4ODAsIDB4MDApfSwgLypXKi8KCXsiR3JlZW4iLAlSR0IoMHgwMCwgMHg2NCwgMHgxMSl9LCAvKk0qLwoJeyJsaWdodGdyZWVuIiwJUkdCKDB4QTAsIDB4RkYsIDB4QTApfSwgLypXKi8KCXsiRGFya0N5YW4iLAlSR0IoMHgwMCwgMHg4MCwgMHg4MCl9LCAvKlcgPzB4MzA3RDdFICovCgl7ImN5YW4iLAlSR0IoMHgwMiwgMHhBQiwgMHhFQSl9LCAvKk0qLwoJeyJsaWdodGN5YW4iLAlSR0IoMHhBMCwgMHhGRiwgMHhGRil9LCAvKlcqLwoJeyJkYXJrbWFnZW50YSIsCVJHQigweDgwLCAweDAwLCAweDgwKX0sIC8qVyovCgl7Im1hZ2VudGEiLAlSR0IoMHhGMiwgMHgwOCwgMHg4NCl9LCAvKk0qLwoJeyJsaWdodG1hZ2VudGEiLFJHQigweEYwLCAweEEwLCAweEYwKX0sIC8qVyovCgl7ImJyb3duIiwJUkdCKDB4ODAsIDB4NDAsIDB4NDApfSwgLypXKi8KCXsieWVsbG93IiwJUkdCKDB4RkMsIDB4RjMsIDB4MDUpfSwgLypNKi8KCXsibGlnaHR5ZWxsb3ciLAlSR0IoMHhGRiwgMHhGRiwgMHhBMCl9LCAvKk0qLwoJeyJkYXJreWVsbG93IiwJUkdCKDB4QkIsIDB4QkIsIDB4MDApfSwgLypVKi8KCXsiU2VhR3JlZW4iLAlSR0IoMHgyRSwgMHg4QiwgMHg1Nyl9LCAvKlcgMHg0RTg5NzUgKi8KCXsib3JhbmdlIiwJUkdCKDB4RkMsIDB4ODAsIDB4MDApfSwgLypXIDB4Rjg3QTE3ICovCgl7IlB1cnBsZSIsCVJHQigweEEwLCAweDIwLCAweEYwKX0sIC8qVyAweDhlMzVlNSAqLwoJeyJTbGF0ZUJsdWUiLAlSR0IoMHg2QSwgMHg1QSwgMHhDRCl9LCAvKlcgMHg3MzdDQTEgKi8KCXsiVmlvbGV0IiwJUkdCKDB4OEQsIDB4MzgsIDB4QzkpfSwgLypVKi8KICAgIH07CgogICAgaW50CQlyLCBnLCBiOwogICAgaW50CQlpOwoKICAgIGlmIChuYW1lWzBdID09ICcjJyAmJiBzdHJsZW4oKGNoYXIgKikgbmFtZSkgPT0gNykKICAgIHsKCS8qIE5hbWUgaXMgaW4gIiNycmdnYmIiIGZvcm1hdCAqLwoJciA9IGhleF9kaWdpdChuYW1lWzFdKSAqIDE2ICsgaGV4X2RpZ2l0KG5hbWVbMl0pOwoJZyA9IGhleF9kaWdpdChuYW1lWzNdKSAqIDE2ICsgaGV4X2RpZ2l0KG5hbWVbNF0pOwoJYiA9IGhleF9kaWdpdChuYW1lWzVdKSAqIDE2ICsgaGV4X2RpZ2l0KG5hbWVbNl0pOwoJaWYgKHIgPCAwIHx8IGcgPCAwIHx8IGIgPCAwKQoJICAgIHJldHVybiBJTlZBTENPTE9SOwoJcmV0dXJuIFJHQihyLCBnLCBiKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChTVFJJQ01QKG5hbWUsICJoaWxpdGUiKSA9PSAwKQoJewoJICAgIExNR2V0SGlsaXRlUkdCKCZNYWNDb2xvcik7CgkgICAgcmV0dXJuIChSR0IoTWFjQ29sb3IucmVkID4+IDgsIE1hY0NvbG9yLmdyZWVuID4+IDgsIE1hY0NvbG9yLmJsdWUgPj4gOCkpOwoJfQoJLyogQ2hlY2sgaWYgdGhlIG5hbWUgaXMgb25lIG9mIHRoZSBjb2xvcnMgd2Uga25vdyAqLwoJZm9yIChpID0gMDsgaSA8IHNpemVvZih0YWJsZSkgLyBzaXplb2YodGFibGVbMF0pOyBpKyspCgkgICAgaWYgKFNUUklDTVAobmFtZSwgdGFibGVbaV0ubmFtZSkgPT0gMCkKCQlyZXR1cm4gdGFibGVbaV0uY29sb3I7CiAgICB9CgogICAgLyoKICAgICAqIExhc3QgYXR0ZW1wdC4gTG9vayBpbiB0aGUgZmlsZSAiJFZJTS9yZ2IudHh0Ii4KICAgICAqLwogICAgewojZGVmaW5lIExJTkVfTEVOIDEwMAoJRklMRQkqZmQ7CgljaGFyCWxpbmVbTElORV9MRU5dOwoJY2hhcl91CSpmbmFtZTsKCglmbmFtZSA9IGV4cGFuZF9lbnZfc2F2ZSgoY2hhcl91ICopIiRWSU1SVU5USU1FL3JnYi50eHQiKTsKCWlmIChmbmFtZSA9PSBOVUxMKQoJICAgIHJldHVybiBJTlZBTENPTE9SOwoKCWZkID0gZm9wZW4oKGNoYXIgKilmbmFtZSwgInJ0Iik7Cgl2aW1fZnJlZShmbmFtZSk7CglpZiAoZmQgPT0gTlVMTCkKCSAgICByZXR1cm4gSU5WQUxDT0xPUjsKCgl3aGlsZSAoIWZlb2YoZmQpKQoJewoJICAgIGludAkJbGVuOwoJICAgIGludAkJcG9zOwoJICAgIGNoYXIJKmNvbG9yOwoKCSAgICBmZ2V0cyhsaW5lLCBMSU5FX0xFTiwgZmQpOwoJICAgIGxlbiA9IHN0cmxlbihsaW5lKTsKCgkgICAgaWYgKGxlbiA8PSAxIHx8IGxpbmVbbGVuLTFdICE9ICdcbicpCgkJY29udGludWU7CgoJICAgIGxpbmVbbGVuLTFdID0gJ1wwJzsKCgkgICAgaSA9IHNzY2FuZihsaW5lLCAiJWQgJWQgJWQgJW4iLCAmciwgJmcsICZiLCAmcG9zKTsKCSAgICBpZiAoaSAhPSAzKQoJCWNvbnRpbnVlOwoKCSAgICBjb2xvciA9IGxpbmUgKyBwb3M7CgoJICAgIGlmIChTVFJJQ01QKGNvbG9yLCBuYW1lKSA9PSAwKQoJICAgIHsKCQlmY2xvc2UoZmQpOwoJCXJldHVybiAoZ3VpY29sb3JfVCkgUkdCKHIsIGcsIGIpOwoJICAgIH0KCX0KCWZjbG9zZShmZCk7CiAgICB9CgogICAgcmV0dXJuIElOVkFMQ09MT1I7Cn0KCi8qCiAqIFNldCB0aGUgY3VycmVudCB0ZXh0IGZvcmVncm91bmQgY29sb3IuCiAqLwogICAgdm9pZApndWlfbWNoX3NldF9mZ19jb2xvcihndWljb2xvcl9UIGNvbG9yKQp7CiAgICBSR0JDb2xvciBUaGVDb2xvcjsKCiAgICBUaGVDb2xvci5yZWQgPSBSZWQoY29sb3IpICogMHgwMTAxOwogICAgVGhlQ29sb3IuZ3JlZW4gPSBHcmVlbihjb2xvcikgKiAweDAxMDE7CiAgICBUaGVDb2xvci5ibHVlID0gQmx1ZShjb2xvcikgKiAweDAxMDE7CgogICAgUkdCRm9yZUNvbG9yKCZUaGVDb2xvcik7Cn0KCi8qCiAqIFNldCB0aGUgY3VycmVudCB0ZXh0IGJhY2tncm91bmQgY29sb3IuCiAqLwogICAgdm9pZApndWlfbWNoX3NldF9iZ19jb2xvcihndWljb2xvcl9UIGNvbG9yKQp7CiAgICBSR0JDb2xvciBUaGVDb2xvcjsKCiAgICBUaGVDb2xvci5yZWQgPSBSZWQoY29sb3IpICogMHgwMTAxOwogICAgVGhlQ29sb3IuZ3JlZW4gPSBHcmVlbihjb2xvcikgKiAweDAxMDE7CiAgICBUaGVDb2xvci5ibHVlID0gQmx1ZShjb2xvcikgKiAweDAxMDE7CgogICAgUkdCQmFja0NvbG9yKCZUaGVDb2xvcik7Cn0KClJHQkNvbG9yIHNwZWNpYWxDb2xvcjsKCi8qCiAqIFNldCB0aGUgY3VycmVudCB0ZXh0IHNwZWNpYWwgY29sb3IuCiAqLwogICAgdm9pZApndWlfbWNoX3NldF9zcF9jb2xvcihndWljb2xvcl9UIGNvbG9yKQp7CiAgICBzcGVjaWFsQ29sb3IucmVkID0gUmVkKGNvbG9yKSAqIDB4MDEwMTsKICAgIHNwZWNpYWxDb2xvci5ncmVlbiA9IEdyZWVuKGNvbG9yKSAqIDB4MDEwMTsKICAgIHNwZWNpYWxDb2xvci5ibHVlID0gQmx1ZShjb2xvcikgKiAweDAxMDE7Cn0KCi8qCiAqIERyYXcgdW5kZXJjdXJsIGF0IHRoZSBib3R0b20gb2YgdGhlIGNoYXJhY3RlciBjZWxsLgogKi8KICAgIHN0YXRpYyB2b2lkCmRyYXdfdW5kZXJjdXJsKGludCBmbGFncywgaW50IHJvdywgaW50IGNvbCwgaW50IGNlbGxzKQp7CiAgICBpbnQJCQl4OwogICAgaW50CQkJb2Zmc2V0OwogICAgY29uc3Qgc3RhdGljIGludAl2YWxbOF0gPSB7MSwgMCwgMCwgMCwgMSwgMiwgMiwgMiB9OwogICAgaW50CQkJeSA9IEZJTExfWShyb3cgKyAxKSAtIDE7CgogICAgUkdCRm9yZUNvbG9yKCZzcGVjaWFsQ29sb3IpOwoKICAgIG9mZnNldCA9IHZhbFtGSUxMX1goY29sKSAlIDhdOwogICAgTW92ZVRvKEZJTExfWChjb2wpLCB5IC0gb2Zmc2V0KTsKCiAgICBmb3IgKHggPSBGSUxMX1goY29sKTsgeCA8IEZJTExfWChjb2wgKyBjZWxscyk7ICsreCkKICAgIHsKCW9mZnNldCA9IHZhbFt4ICUgOF07CglMaW5lVG8oeCwgeSAtIG9mZnNldCk7CiAgICB9Cn0KCgogICAgc3RhdGljIHZvaWQKZHJhd19zdHJpbmdfUUQoaW50IHJvdywgaW50IGNvbCwgY2hhcl91ICpzLCBpbnQgbGVuLCBpbnQgZmxhZ3MpCnsKI2lmZGVmIEZFQVRfTUJZVEUKICAgIGNoYXJfdQkqdG9mcmVlID0gTlVMTDsKCiAgICBpZiAob3V0cHV0X2NvbnYudmNfdHlwZSAhPSBDT05WX05PTkUpCiAgICB7Cgl0b2ZyZWUgPSBzdHJpbmdfY29udmVydCgmb3V0cHV0X2NvbnYsIHMsICZsZW4pOwoJaWYgKHRvZnJlZSAhPSBOVUxMKQoJICAgIHMgPSB0b2ZyZWU7CiAgICB9CiNlbmRpZgoKICAgIC8qCiAgICAgKiBPbiBPUyBYLCB0cnkgdXNpbmcgUXVhcnR6LXN0eWxlIHRleHQgYW50aWFsaWFzaW5nLgogICAgICovCiAgICBpZiAoZ01hY1N5c3RlbVZlcnNpb24gPj0gMHgxMDIwKQogICAgewoJLyogUXVhcnR6IGFudGlhbGlhc2luZyBpcyBhdmFpbGFibGUgb25seSBpbiBPUyAxMC4yIGFuZCBsYXRlci4gKi8KCVVJbnQzMiBxZF9mbGFncyA9IChwX2FudGlhbGlhcyA/CgkJCSAgICAga1FEVXNlQ0dUZXh0UmVuZGVyaW5nIHwga1FEVXNlQ0dUZXh0TWV0cmljcyA6IDApOwoJUURTd2FwVGV4dEZsYWdzKHFkX2ZsYWdzKTsKICAgIH0KCiAgICAvKgogICAgICogV2hlbiBhbnRpYWxpYXNpbmcgd2UncmUgdXNpbmcgc3JjT3IgbW9kZSwgd2UgaGF2ZSB0byBjbGVhciB0aGUgYmxvY2sKICAgICAqIGJlZm9yZSBkcmF3aW5nIHRoZSB0ZXh0LgogICAgICogQWxzbyBuZWVkZWQgd2hlbiAnbGluZXNwYWNlJyBpcyBub24temVybyB0byByZW1vdmUgdGhlIGN1cnNvciBhbmQKICAgICAqIHVuZGVybGluaW5nLgogICAgICogQnV0IG5vdCB3aGVuIGRyYXdpbmcgdHJhbnNwYXJlbnRseS4KICAgICAqIFRoZSBmb2xsb3dpbmcgaXMgbGlrZSBjYWxsaW5nIGd1aV9tY2hfY2xlYXJfYmxvY2socm93LCBjb2wsIHJvdywgY29sICsKICAgICAqIGxlbiAtIDEpLCBidXQgd2l0aG91dCBzZXR0aW5nIHRoZSBiZyBjb2xvciB0byBndWkuYmFja19waXhlbC4KICAgICAqLwogICAgaWYgKCgoZ01hY1N5c3RlbVZlcnNpb24gPj0gMHgxMDIwICYmIHBfYW50aWFsaWFzKSB8fCBwX2xpbmVzcGFjZSAhPSAwKQoJICAgICYmICEoZmxhZ3MgJiBEUkFXX1RSQU5TUCkpCiAgICB7CglSZWN0IHJjOwoKCXJjLmxlZnQgPSBGSUxMX1goY29sKTsKCXJjLnRvcCA9IEZJTExfWShyb3cpOwojaWZkZWYgRkVBVF9NQllURQoJLyogTXVsdGlieXRlIGNvbXB1dGF0aW9uIHRha2VuIGZyb20gZ3VpX3czMi5jICovCglpZiAoaGFzX21ieXRlKQoJewoJICAgIGludCBjZWxsX2xlbiA9IDA7CgkgICAgaW50IG47CgoJICAgIC8qIENvbXB1dGUgdGhlIGxlbmd0aCBpbiBkaXNwbGF5IGNlbGxzLiAqLwoJICAgIGZvciAobiA9IDA7IG4gPCBsZW47IG4gKz0gTUJfQllURTJMRU4oc1tuXSkpCgkJY2VsbF9sZW4gKz0gKCptYl9wdHIyY2VsbHMpKHMgKyBuKTsKCSAgICByYy5yaWdodCA9IEZJTExfWChjb2wgKyBjZWxsX2xlbik7Cgl9CgllbHNlCiNlbmRpZgoJcmMucmlnaHQgPSBGSUxMX1goY29sICsgbGVuKSArIChjb2wgKyBsZW4gPT0gQ29sdW1ucyk7CglyYy5ib3R0b20gPSBGSUxMX1kocm93ICsgMSk7CglFcmFzZVJlY3QoJnJjKTsKICAgIH0KCiAgICBpZiAoZ01hY1N5c3RlbVZlcnNpb24gPj0gMHgxMDIwICYmIHBfYW50aWFsaWFzKQogICAgewoJU3R5bGVQYXJhbWV0ZXIgZmFjZTsKCglmYWNlID0gbm9ybWFsOwoJaWYgKGZsYWdzICYgRFJBV19CT0xEKQoJICAgIGZhY2UgfD0gYm9sZDsKCWlmIChmbGFncyAmIERSQVdfVU5ERVJMKQoJICAgIGZhY2UgfD0gdW5kZXJsaW5lOwoJVGV4dEZhY2UoZmFjZSk7CgoJLyogUXVhcnR6IGFudGlhbGlhc2luZyB3b3JrcyBvbmx5IGluIHNyY09yIHRyYW5zZmVyIG1vZGUuICovCglUZXh0TW9kZShzcmNPcik7CgoJTW92ZVRvKFRFWFRfWChjb2wpLCBURVhUX1kocm93KSk7CglEcmF3VGV4dCgoY2hhciopcywgMCwgbGVuKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCS8qIFVzZSBvbGQtc3R5bGUsIG5vbi1hbnRpYWxpYXNlZCBRdWlja0RyYXcgdGV4dCByZW5kZXJpbmcuICovCglUZXh0TW9kZShzcmNDb3B5KTsKCVRleHRGYWNlKG5vcm1hbCk7CgogICAgLyogIFNlbGVjdEZvbnQoaGRjLCBndWkuY3VyckZvbnQpOyAqLwoKCWlmIChmbGFncyAmIERSQVdfVFJBTlNQKQoJewoJICAgIFRleHRNb2RlKHNyY09yKTsKCX0KCglNb3ZlVG8oVEVYVF9YKGNvbCksIFRFWFRfWShyb3cpKTsKCURyYXdUZXh0KChjaGFyICopcywgMCwgbGVuKTsKCglpZiAoZmxhZ3MgJiBEUkFXX0JPTEQpCgl7CgkgICAgVGV4dE1vZGUoc3JjT3IpOwoJICAgIE1vdmVUbyhURVhUX1goY29sKSArIDEsIFRFWFRfWShyb3cpKTsKCSAgICBEcmF3VGV4dCgoY2hhciAqKXMsIDAsIGxlbik7Cgl9CgoJaWYgKGZsYWdzICYgRFJBV19VTkRFUkwpCgl7CgkgICAgTW92ZVRvKEZJTExfWChjb2wpLCBGSUxMX1kocm93ICsgMSkgLSAxKTsKCSAgICBMaW5lVG8oRklMTF9YKGNvbCArIGxlbikgLSAxLCBGSUxMX1kocm93ICsgMSkgLSAxKTsKCX0KICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBEUkFXX1VOREVSQykKCWRyYXdfdW5kZXJjdXJsKGZsYWdzLCByb3csIGNvbCwgbGVuKTsKCiNpZmRlZiBGRUFUX01CWVRFCiAgICB2aW1fZnJlZSh0b2ZyZWUpOwojZW5kaWYKfQoKI2lmZGVmIFVTRV9BVFNVSV9EUkFXSU5HCgogICAgc3RhdGljIHZvaWQKZHJhd19zdHJpbmdfQVRTVUkoaW50IHJvdywgaW50IGNvbCwgY2hhcl91ICpzLCBpbnQgbGVuLCBpbnQgZmxhZ3MpCnsKICAgIC8qIEFUU1VJIHJlcXVpcmVzIHV0Zi0xNiBzdHJpbmdzICovCiAgICBVbmlDaGFyQ291bnQgdXRmMTZfbGVuOwogICAgVW5pQ2hhciAqdG9mcmVlID0gbWFjX2VuY190b191dGYxNihzLCBsZW4sIChzaXplX3QgKikmdXRmMTZfbGVuKTsKICAgIHV0ZjE2X2xlbiAvPSBzaXplb2YoVW5pQ2hhcik7CgogICAgLyogLSBBVFNVSSBhdXRvbWF0aWNhbGx5IGFudGlhbGlhc2VzIHRleHQgKFNvbWVvbmUpCiAgICAgKiAtIGZvciBzb21lIHJlYXNvbiBpdCBkb2VzIG5vdCB3b3JrLi4uIChKdXNzaSkgKi8KCiAgICAvKgogICAgICogV2hlbiBhbnRpYWxpYXNpbmcgd2UncmUgdXNpbmcgc3JjT3IgbW9kZSwgd2UgaGF2ZSB0byBjbGVhciB0aGUgYmxvY2sKICAgICAqIGJlZm9yZSBkcmF3aW5nIHRoZSB0ZXh0LgogICAgICogQWxzbyBuZWVkZWQgd2hlbiAnbGluZXNwYWNlJyBpcyBub24temVybyB0byByZW1vdmUgdGhlIGN1cnNvciBhbmQKICAgICAqIHVuZGVybGluaW5nLgogICAgICogQnV0IG5vdCB3aGVuIGRyYXdpbmcgdHJhbnNwYXJlbnRseS4KICAgICAqIFRoZSBmb2xsb3dpbmcgaXMgbGlrZSBjYWxsaW5nIGd1aV9tY2hfY2xlYXJfYmxvY2socm93LCBjb2wsIHJvdywgY29sICsKICAgICAqIGxlbiAtIDEpLCBidXQgd2l0aG91dCBzZXR0aW5nIHRoZSBiZyBjb2xvciB0byBndWkuYmFja19waXhlbC4KICAgICAqLwogICAgaWYgKChmbGFncyAmIERSQVdfVFJBTlNQKSA9PSAwKQogICAgewoJUmVjdCByYzsKCglyYy5sZWZ0ID0gRklMTF9YKGNvbCk7CglyYy50b3AgPSBGSUxMX1kocm93KTsKCS8qIE11bHRpYnl0ZSBjb21wdXRhdGlvbiB0YWtlbiBmcm9tIGd1aV93MzIuYyAqLwoJaWYgKGhhc19tYnl0ZSkKCXsKCSAgICBpbnQgY2VsbF9sZW4gPSAwOwoJICAgIGludCBuOwoKCSAgICAvKiBDb21wdXRlIHRoZSBsZW5ndGggaW4gZGlzcGxheSBjZWxscy4gKi8KCSAgICBmb3IgKG4gPSAwOyBuIDwgbGVuOyBuICs9IE1CX0JZVEUyTEVOKHNbbl0pKQoJCWNlbGxfbGVuICs9ICgqbWJfcHRyMmNlbGxzKShzICsgbik7CgkgICAgcmMucmlnaHQgPSBGSUxMX1goY29sICsgY2VsbF9sZW4pOwoJfQoJZWxzZQoJICAgIHJjLnJpZ2h0ID0gRklMTF9YKGNvbCArIGxlbikgKyAoY29sICsgbGVuID09IENvbHVtbnMpOwoKCXJjLmJvdHRvbSA9IEZJTExfWShyb3cgKyAxKTsKCUVyYXNlUmVjdCgmcmMpOwogICAgfQoKICAgIHsKCS8qIFVzZSBvbGQtc3R5bGUsIG5vbi1hbnRpYWxpYXNlZCBRdWlja0RyYXcgdGV4dCByZW5kZXJpbmcuICovCglUZXh0TW9kZShzcmNDb3B5KTsKCVRleHRGYWNlKG5vcm1hbCk7CgogICAgLyogIFNlbGVjdEZvbnQoaGRjLCBndWkuY3VyckZvbnQpOyAqLwoKCWlmIChmbGFncyAmIERSQVdfVFJBTlNQKQoJewoJICAgIFRleHRNb2RlKHNyY09yKTsKCX0KCglNb3ZlVG8oVEVYVF9YKGNvbCksIFRFWFRfWShyb3cpKTsKCUFUU1VUZXh0TGF5b3V0IHRleHRMYXlvdXQ7CgoJaWYgKEFUU1VDcmVhdGVUZXh0TGF5b3V0V2l0aFRleHRQdHIodG9mcmVlLAoJCSAgICBrQVRTVUZyb21UZXh0QmVnaW5uaW5nLCBrQVRTVVRvVGV4dEVuZCwKCQkgICAgdXRmMTZfbGVuLAoJCSAgICAoZ0ZvbnRTdHlsZSA/IDEgOiAwKSwgJnV0ZjE2X2xlbiwKCQkgICAgKGdGb250U3R5bGUgPyAmZ0ZvbnRTdHlsZSA6IE5VTEwpLAoJCSAgICAmdGV4dExheW91dCkgPT0gbm9FcnIpCgl7CgkgICAgQVRTVVNldFRyYW5zaWVudEZvbnRNYXRjaGluZyh0ZXh0TGF5b3V0LCBUUlVFKTsKCgkgICAgQVRTVURyYXdUZXh0KHRleHRMYXlvdXQsCgkJICAgIGtBVFNVRnJvbVRleHRCZWdpbm5pbmcsIGtBVFNVVG9UZXh0RW5kLAoJCSAgICBrQVRTVVVzZUdyYWZQb3J0UGVuTG9jLCBrQVRTVVVzZUdyYWZQb3J0UGVuTG9jKTsKCgkgICAgQVRTVURpc3Bvc2VUZXh0TGF5b3V0KHRleHRMYXlvdXQpOwoJfQogICAgfQoKICAgIGlmIChmbGFncyAmIERSQVdfVU5ERVJDKQoJZHJhd191bmRlcmN1cmwoZmxhZ3MsIHJvdywgY29sLCBsZW4pOwoKICAgIHZpbV9mcmVlKHRvZnJlZSk7Cn0KI2VuZGlmCgogICAgdm9pZApndWlfbWNoX2RyYXdfc3RyaW5nKGludCByb3csIGludCBjb2wsIGNoYXJfdSAqcywgaW50IGxlbiwgaW50IGZsYWdzKQp7CiNpZiBkZWZpbmVkKFVTRV9BVFNVSV9EUkFXSU5HKQogICAgaWYgKHBfbWFjYXRzdWkpCglkcmF3X3N0cmluZ19BVFNVSShyb3csIGNvbCwgcywgbGVuLCBmbGFncyk7CiAgICBlbHNlCiNlbmRpZgoJZHJhd19zdHJpbmdfUUQocm93LCBjb2wsIHMsIGxlbiwgZmxhZ3MpOwp9CgovKgogKiBSZXR1cm4gT0sgaWYgdGhlIGtleSB3aXRoIHRoZSB0ZXJtY2FwIG5hbWUgIm5hbWUiIGlzIHN1cHBvcnRlZC4KICovCiAgICBpbnQKZ3VpX21jaF9oYXNrZXkoY2hhcl91ICpuYW1lKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGkgPSAwOyBzcGVjaWFsX2tleXNbaV0ua2V5X3N5bSAhPSAoS2V5U3ltKTA7IGkrKykKCWlmIChuYW1lWzBdID09IHNwZWNpYWxfa2V5c1tpXS52aW1fY29kZTAgJiYKCQkJCQkgbmFtZVsxXSA9PSBzcGVjaWFsX2tleXNbaV0udmltX2NvZGUxKQoJICAgIHJldHVybiBPSzsKICAgIHJldHVybiBGQUlMOwp9CgogICAgdm9pZApndWlfbWNoX2JlZXAodm9pZCkKewogICAgU3lzQmVlcCgxKTsgLyogU2hvdWxkIHRoaXMgYmUgMD8gKD8/Pz8pICovCn0KCiAgICB2b2lkCmd1aV9tY2hfZmxhc2goaW50IG1zZWMpCnsKICAgIC8qIERvIGEgdmlzdWFsIGJlZXAgYnkgcmV2ZXJzaW5nIHRoZSBmb3JlZ3JvdW5kIGFuZCBiYWNrZ3JvdW5kIGNvbG9ycyAqLwogICAgUmVjdCAgICByYzsKCiAgICAvKgogICAgICogTm90ZTogSW52ZXJ0UmVjdCgpIGV4Y2x1ZGVzIHJpZ2h0IGFuZCBib3R0b20gb2YgcmVjdGFuZ2xlLgogICAgICovCiAgICByYy5sZWZ0ID0gMDsKICAgIHJjLnRvcCA9IDA7CiAgICByYy5yaWdodCA9IGd1aS5udW1fY29scyAqIGd1aS5jaGFyX3dpZHRoOwogICAgcmMuYm90dG9tID0gZ3VpLm51bV9yb3dzICogZ3VpLmNoYXJfaGVpZ2h0OwogICAgSW52ZXJ0UmVjdCgmcmMpOwoKICAgIHVpX2RlbGF5KChsb25nKW1zZWMsIFRSVUUpOwkJLyogd2FpdCBmb3Igc29tZSBtc2VjICovCgogICAgSW52ZXJ0UmVjdCgmcmMpOwp9CgovKgogKiBJbnZlcnQgYSByZWN0YW5nbGUgZnJvbSByb3cgciwgY29sdW1uIGMsIGZvciBuciByb3dzIGFuZCBuYyBjb2x1bW5zLgogKi8KICAgIHZvaWQKZ3VpX21jaF9pbnZlcnRfcmVjdGFuZ2xlKGludCByLCBpbnQgYywgaW50IG5yLCBpbnQgbmMpCnsKICAgIFJlY3QJcmM7CgogICAgLyoKICAgICAqIE5vdGU6IEludmVydFJlY3QoKSBleGNsdWRlcyByaWdodCBhbmQgYm90dG9tIG9mIHJlY3RhbmdsZS4KICAgICAqLwogICAgcmMubGVmdCA9IEZJTExfWChjKTsKICAgIHJjLnRvcCA9IEZJTExfWShyKTsKICAgIHJjLnJpZ2h0ID0gcmMubGVmdCArIG5jICogZ3VpLmNoYXJfd2lkdGg7CiAgICByYy5ib3R0b20gPSByYy50b3AgKyBuciAqIGd1aS5jaGFyX2hlaWdodDsKICAgIEludmVydFJlY3QoJnJjKTsKfQoKLyoKICogSWNvbmlmeSB0aGUgR1VJIHdpbmRvdy4KICovCiAgICB2b2lkCmd1aV9tY2hfaWNvbmlmeSh2b2lkKQp7CiAgICAvKiBUT0RPOiBmaW5kIG91dCB3aGF0IGNvdWxkIHJlcGxhY2UgaWNvbmlmeQogICAgICoJICAgICAtd2luZG93IHNoYWRlPwogICAgICoJICAgICAtaGlkZSBhcHBsaWNhdGlvbj8KICAgICAqLwp9CgojaWYgZGVmaW5lZChGRUFUX0VWQUwpIHx8IGRlZmluZWQoUFJPVE8pCi8qCiAqIEJyaW5nIHRoZSBWaW0gd2luZG93IHRvIHRoZSBmb3JlZ3JvdW5kLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zZXRfZm9yZWdyb3VuZCh2b2lkKQp7CiAgICAvKiBUT0RPICovCn0KI2VuZGlmCgovKgogKiBEcmF3IGEgY3Vyc29yIHdpdGhvdXQgZm9jdXMuCiAqLwogICAgdm9pZApndWlfbWNoX2RyYXdfaG9sbG93X2N1cnNvcihndWljb2xvcl9UIGNvbG9yKQp7CiAgICBSZWN0IHJjOwoKICAgIC8qCiAgICAgKiBOb3RlOiBGcmFtZVJlY3QoKSBleGNsdWRlcyByaWdodCBhbmQgYm90dG9tIG9mIHJlY3RhbmdsZS4KICAgICAqLwogICAgcmMubGVmdCA9IEZJTExfWChndWkuY29sKTsKICAgIHJjLnRvcCA9IEZJTExfWShndWkucm93KTsKICAgIHJjLnJpZ2h0ID0gcmMubGVmdCArIGd1aS5jaGFyX3dpZHRoOwojaWZkZWYgRkVBVF9NQllURQogICAgaWYgKG1iX2xlZnRoYWx2ZShndWkucm93LCBndWkuY29sKSkKCXJjLnJpZ2h0ICs9IGd1aS5jaGFyX3dpZHRoOwojZW5kaWYKICAgIHJjLmJvdHRvbSA9IHJjLnRvcCArIGd1aS5jaGFyX2hlaWdodDsKCiAgICBndWlfbWNoX3NldF9mZ19jb2xvcihjb2xvcik7CgogICAgRnJhbWVSZWN0KCZyYyk7Cn0KCi8qCiAqIERyYXcgcGFydCBvZiBhIGN1cnNvciwgb25seSB3IHBpeGVscyB3aWRlLCBhbmQgaCBwaXhlbHMgaGlnaC4KICovCiAgICB2b2lkCmd1aV9tY2hfZHJhd19wYXJ0X2N1cnNvcihpbnQgdywgaW50IGgsIGd1aWNvbG9yX1QgY29sb3IpCnsKICAgIFJlY3QgcmM7CgojaWZkZWYgRkVBVF9SSUdIVExFRlQKICAgIC8qIHZlcnRpY2FsIGxpbmUgc2hvdWxkIGJlIG9uIHRoZSByaWdodCBvZiBjdXJyZW50IHBvaW50ICovCiAgICBpZiAoQ1VSU09SX0JBUl9SSUdIVCkKCXJjLmxlZnQgPSBGSUxMX1goZ3VpLmNvbCArIDEpIC0gdzsKICAgIGVsc2UKI2VuZGlmCglyYy5sZWZ0ID0gRklMTF9YKGd1aS5jb2wpOwogICAgcmMudG9wID0gRklMTF9ZKGd1aS5yb3cpICsgZ3VpLmNoYXJfaGVpZ2h0IC0gaDsKICAgIHJjLnJpZ2h0ID0gcmMubGVmdCArIHc7CiAgICByYy5ib3R0b20gPSByYy50b3AgKyBoOwoKICAgIGd1aV9tY2hfc2V0X2ZnX2NvbG9yKGNvbG9yKTsKCiAgICBGcmFtZVJlY3QoJnJjKTsKLy8gICAgUGFpbnRSZWN0KCZyYyk7Cn0KCgoKLyoKICogQ2F0Y2ggdXAgd2l0aCBhbnkgcXVldWVkIFggZXZlbnRzLiAgVGhpcyBtYXkgcHV0IGtleWJvYXJkIGlucHV0IGludG8gdGhlCiAqIGlucHV0IGJ1ZmZlciwgY2FsbCByZXNpemUgY2FsbC1iYWNrcywgdHJpZ2dlciB0aW1lcnMgZXRjLiAgSWYgdGhlcmUgaXMKICogbm90aGluZyBpbiB0aGUgWCBldmVudCBxdWV1ZSAoJiBubyB0aW1lcnMgcGVuZGluZyksIHRoZW4gd2UgcmV0dXJuCiAqIGltbWVkaWF0ZWx5LgogKi8KICAgIHZvaWQKZ3VpX21jaF91cGRhdGUodm9pZCkKewogICAgLyogVE9ETzogZmluZCB3aGF0IHRvIGRvCiAgICAgKgkgICAgIG1heWJlIGNhbGwgZ3VpX21jaF93YWl0X2Zvcl9jaGFycyAoMCkKICAgICAqCSAgICAgbW9yZSBsaWtlIGxvb2sgYXQgRXZlbnRRdWV1ZSB0aGVuCiAgICAgKgkgICAgIGNhbGwgaGVhcnQgb2YgZ3VpX21jaF93YWl0X2Zvcl9jaGFyczsKICAgICAqCiAgICAgKglpZiAoZXZlbnR0aGVyKQogICAgICoJICAgIGd1aV9tYWNfaGFuZGxlX2V2ZW50KCZldmVudCk7CiAgICAgKi8KICAgIEV2ZW50UmVjb3JkIHRoZUV2ZW50OwoKICAgIGlmIChFdmVudEF2YWlsKGV2ZXJ5RXZlbnQsICZ0aGVFdmVudCkpCglpZiAodGhlRXZlbnQud2hhdCAhPSBudWxsRXZlbnQpCgkgICAgZ3VpX21jaF93YWl0X2Zvcl9jaGFycygwKTsKfQoKLyoKICogU2ltcGxlIHdyYXBwZXIgdG8gbmVnbGVjdCBtb3JlIGVhc2lseSB0aGUgdGltZQogKiBzcGVudCBpbnNpZGUgV2FpdE5leHRFdmVudCB3aGlsZSBwcm9maWxpbmcuCiAqLwoKICAgIHBhc2NhbAogICAgQm9vbGVhbgpXYWl0TmV4dEV2ZW50V3JwKEV2ZW50TWFzayBldmVudE1hc2ssIEV2ZW50UmVjb3JkICp0aGVFdmVudCwgVUludDMyIHNsZWVwLCBSZ25IYW5kbGUgbW91c2VSZ24pCnsKICAgIGlmICgoKGxvbmcpIHNsZWVwKSA8IC0xKQoJc2xlZXAgPSAzMjc2NzsKICAgIHJldHVybiBXYWl0TmV4dEV2ZW50KGV2ZW50TWFzaywgdGhlRXZlbnQsIHNsZWVwLCBtb3VzZVJnbik7Cn0KCi8qCiAqIEdVSSBpbnB1dCByb3V0aW5lIGNhbGxlZCBieSBndWlfd2FpdF9mb3JfY2hhcnMoKS4gIFdhaXRzIGZvciBhIGNoYXJhY3RlcgogKiBmcm9tIHRoZSBrZXlib2FyZC4KICogIHd0aW1lID09IC0xCSAgICBXYWl0IGZvcmV2ZXIuCiAqICB3dGltZSA9PSAwCSAgICBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4uCiAqICB3dGltZSA+IDAJICAgIFdhaXQgd3RpbWUgbWlsbGlzZWNvbmRzIGZvciBhIGNoYXJhY3Rlci4KICogUmV0dXJucyBPSyBpZiBhIGNoYXJhY3RlciB3YXMgZm91bmQgdG8gYmUgYXZhaWxhYmxlIHdpdGhpbiB0aGUgZ2l2ZW4gdGltZSwKICogb3IgRkFJTCBvdGhlcndpc2UuCiAqLwogICAgaW50Cmd1aV9tY2hfd2FpdF9mb3JfY2hhcnMoaW50IHd0aW1lKQp7CiAgICBFdmVudE1hc2sJbWFzayAgPSAoZXZlcnlFdmVudCk7CiAgICBFdmVudFJlY29yZCBldmVudDsKICAgIGxvbmcJZW50cnlUaWNrOwogICAgbG9uZwljdXJyZW50VGljazsKICAgIGxvbmcJc2xlZXBweVRpY2s7CgogICAgLyogSWYgd2UgYXJlIHByb3ZpZGluZyBsaWZlIGZlZWRiYWNrIHdpdGggdGhlIHNjcm9sbGJhciwKICAgICAqIHdlIGRvbid0IHdhbnQgdG8gdHJ5IHRvIHdhaXQgZm9yIGFuIGV2ZW50LCBvciBlbHNlCiAgICAgKiB0aGVyZSB3b24ndCBiZSBhbnkgbGlmZSBmZWVkYmFjay4KICAgICAqLwogICAgaWYgKGRyYWdnZWRfc2IgIT0gTlVMTCkKCXJldHVybiBGQUlMOwoJLyogVE9ETzogQ2hlY2sgaWYgRkFJTCBpcyB0aGUgcHJvcGVyIHJldHVybiBjb2RlICovCgogICAgZW50cnlUaWNrID0gVGlja0NvdW50KCk7CgogICAgYWxsb3dfc2Nyb2xsYmFyID0gVFJVRTsKCiAgICBkbwogICAgewovKglpZiAoZHJhZ1JlY3RDb250cm9sID09IGtDcmVhdGVFbXB0eSkKCXsKCSAgICBkcmFnUmduID0gTlVMTDsKCSAgICBkcmFnUmVjdENvbnRyb2wgPSBrTm90aGluZzsKCX0KCWVsc2UqLyBpZiAoZHJhZ1JlY3RDb250cm9sID09IGtDcmVhdGVSZWN0KQoJewoJICAgIGRyYWdSZ24gPSBjdXJzb3JSZ247CgkgICAgUmVjdFJnbihkcmFnUmduLCAmZHJhZ1JlY3QpOwoJICAgIGRyYWdSZWN0Q29udHJvbCA9IGtOb3RoaW5nOwoJfQoJLyoKCSAqIERvbid0IHVzZSBndWlfbWNoX3VwZGF0ZSgpIGJlY2F1c2UgdGhlbiB3ZSB3aWxsIHNwaW4tbG9jayB1bnRpbCBhCgkgKiBjaGFyIGFycml2ZXMsIGluc3RlYWQgd2UgdXNlIFdhaXROZXh0RXZlbnRXcnAoKSB0byBoYW5nIHVudGlsIGFuCgkgKiBldmVudCBhcnJpdmVzLiAgTm8gbmVlZCB0byBjaGVjayBmb3IgaW5wdXRfYnVmX2Z1bGwgYmVjYXVzZSB3ZSBhcmUKCSAqIHJldHVybmluZyBhcyBzb29uIGFzIGl0IGNvbnRhaW5zIGEgc2luZ2xlIGNoYXIuCgkgKi8KCS8qIFRPRE86IHJlZHVjZSB3dGltZSBhY2NvcmRpbmx5Pz8/ICAqLwoJaWYgKHd0aW1lID4gLTEpCgkgICAgc2xlZXBweVRpY2sgPSA2MCp3dGltZS8xMDAwOwoJZWxzZQoJICAgIHNsZWVwcHlUaWNrID0gMzI3Njc7CglpZiAoV2FpdE5leHRFdmVudFdycChtYXNrLCAmZXZlbnQsIHNsZWVwcHlUaWNrLCBkcmFnUmduKSkKCXsKCQlndWlfbWFjX2hhbmRsZV9ldmVudCgmZXZlbnQpOwoJICAgIGlmIChpbnB1dF9hdmFpbGFibGUoKSkKCSAgICB7CgkJYWxsb3dfc2Nyb2xsYmFyID0gRkFMU0U7CgkJcmV0dXJuIE9LOwoJICAgIH0KCX0KCWN1cnJlbnRUaWNrID0gVGlja0NvdW50KCk7CiAgICB9CiAgICB3aGlsZSAoKHd0aW1lID09IC0xKSB8fCAoKGN1cnJlbnRUaWNrIC0gZW50cnlUaWNrKSA8IDYwKnd0aW1lLzEwMDApKTsKCiAgICBhbGxvd19zY3JvbGxiYXIgPSBGQUxTRTsKICAgIHJldHVybiBGQUlMOwp9CgovKgogKiBPdXRwdXQgcm91dGluZXMuCiAqLwoKLyogRmx1c2ggYW55IG91dHB1dCB0byB0aGUgc2NyZWVuICovCiAgICB2b2lkCmd1aV9tY2hfZmx1c2godm9pZCkKewogICAgLyogVE9ETzogSXMgYW55dGhpbmcgbmVlZGVkIGhlcmU/ICovCn0KCi8qCiAqIENsZWFyIGEgcmVjdGFuZ3VsYXIgcmVnaW9uIG9mIHRoZSBzY3JlZW4gZnJvbSB0ZXh0IHBvcyAocm93MSwgY29sMSkgdG8KICogKHJvdzIsIGNvbDIpIGluY2x1c2l2ZS4KICovCiAgICB2b2lkCmd1aV9tY2hfY2xlYXJfYmxvY2soaW50IHJvdzEsIGludCBjb2wxLCBpbnQgcm93MiwgaW50IGNvbDIpCnsKICAgIFJlY3QgcmM7CgogICAgLyoKICAgICAqIENsZWFyIG9uZSBleHRyYSBwaXhlbCBhdCB0aGUgZmFyIHJpZ2h0LCBmb3Igd2hlbiBib2xkIGNoYXJhY3RlcnMgaGF2ZQogICAgICogc3BpbGxlZCBvdmVyIHRvIHRoZSBuZXh0IGNvbHVtbi4KICAgICAqLwogICAgcmMubGVmdCA9IEZJTExfWChjb2wxKTsKICAgIHJjLnRvcCA9IEZJTExfWShyb3cxKTsKICAgIHJjLnJpZ2h0ID0gRklMTF9YKGNvbDIgKyAxKSArIChjb2wyID09IENvbHVtbnMgLSAxKTsKICAgIHJjLmJvdHRvbSA9IEZJTExfWShyb3cyICsgMSk7CgogICAgZ3VpX21jaF9zZXRfYmdfY29sb3IoZ3VpLmJhY2tfcGl4ZWwpOwogICAgRXJhc2VSZWN0KCZyYyk7Cn0KCi8qCiAqIENsZWFyIHRoZSB3aG9sZSB0ZXh0IHdpbmRvdy4KICovCiAgICB2b2lkCmd1aV9tY2hfY2xlYXJfYWxsKHZvaWQpCnsKICAgIFJlY3QJcmM7CgogICAgcmMubGVmdCA9IDA7CiAgICByYy50b3AgPSAwOwogICAgcmMucmlnaHQgPSBDb2x1bW5zICogZ3VpLmNoYXJfd2lkdGggKyAyICogZ3VpLmJvcmRlcl93aWR0aDsKICAgIHJjLmJvdHRvbSA9IFJvd3MgKiBndWkuY2hhcl9oZWlnaHQgKyAyICogZ3VpLmJvcmRlcl93aWR0aDsKCiAgICBndWlfbWNoX3NldF9iZ19jb2xvcihndWkuYmFja19waXhlbCk7CiAgICBFcmFzZVJlY3QoJnJjKTsKLyogIGd1aV9tY2hfc2V0X2ZnX2NvbG9yKGd1aS5ub3JtX3BpeGVsKTsKICAgIEZyYW1lUmVjdCgmcmMpOwoqLwp9CgovKgogKiBEZWxldGUgdGhlIGdpdmVuIG51bWJlciBvZiBsaW5lcyBmcm9tIHRoZSBnaXZlbiByb3csIHNjcm9sbGluZyB1cCBhbnkKICogdGV4dCBmdXJ0aGVyIGRvd24gd2l0aGluIHRoZSBzY3JvbGwgcmVnaW9uLgogKi8KICAgIHZvaWQKZ3VpX21jaF9kZWxldGVfbGluZXMoaW50IHJvdywgaW50IG51bV9saW5lcykKewogICAgUmVjdAlyYzsKCiAgICAvKiBjaGFuZ2VkIHdpdGhvdXQgY2hlY2tpbmchICovCiAgICByYy5sZWZ0ID0gRklMTF9YKGd1aS5zY3JvbGxfcmVnaW9uX2xlZnQpOwogICAgcmMucmlnaHQgPSBGSUxMX1goZ3VpLnNjcm9sbF9yZWdpb25fcmlnaHQgKyAxKTsKICAgIHJjLnRvcCA9IEZJTExfWShyb3cpOwogICAgcmMuYm90dG9tID0gRklMTF9ZKGd1aS5zY3JvbGxfcmVnaW9uX2JvdCArIDEpOwoKICAgIGd1aV9tY2hfc2V0X2JnX2NvbG9yKGd1aS5iYWNrX3BpeGVsKTsKICAgIFNjcm9sbFJlY3QoJnJjLCAwLCAtbnVtX2xpbmVzICogZ3VpLmNoYXJfaGVpZ2h0LCAoUmduSGFuZGxlKSBuaWwpOwoKICAgIGd1aV9jbGVhcl9ibG9jayhndWkuc2Nyb2xsX3JlZ2lvbl9ib3QgLSBudW1fbGluZXMgKyAxLAoJCQkJCQkgICAgICAgZ3VpLnNjcm9sbF9yZWdpb25fbGVmdCwKCWd1aS5zY3JvbGxfcmVnaW9uX2JvdCwgZ3VpLnNjcm9sbF9yZWdpb25fcmlnaHQpOwp9CgovKgogKiBJbnNlcnQgdGhlIGdpdmVuIG51bWJlciBvZiBsaW5lcyBiZWZvcmUgdGhlIGdpdmVuIHJvdywgc2Nyb2xsaW5nIGRvd24gYW55CiAqIGZvbGxvd2luZyB0ZXh0IHdpdGhpbiB0aGUgc2Nyb2xsIHJlZ2lvbi4KICovCiAgICB2b2lkCmd1aV9tY2hfaW5zZXJ0X2xpbmVzKGludCByb3csIGludCBudW1fbGluZXMpCnsKICAgIFJlY3QgcmM7CgogICAgcmMubGVmdCA9IEZJTExfWChndWkuc2Nyb2xsX3JlZ2lvbl9sZWZ0KTsKICAgIHJjLnJpZ2h0ID0gRklMTF9YKGd1aS5zY3JvbGxfcmVnaW9uX3JpZ2h0ICsgMSk7CiAgICByYy50b3AgPSBGSUxMX1kocm93KTsKICAgIHJjLmJvdHRvbSA9IEZJTExfWShndWkuc2Nyb2xsX3JlZ2lvbl9ib3QgKyAxKTsKCiAgICBndWlfbWNoX3NldF9iZ19jb2xvcihndWkuYmFja19waXhlbCk7CgogICAgU2Nyb2xsUmVjdCgmcmMsIDAsIGd1aS5jaGFyX2hlaWdodCAqIG51bV9saW5lcywgKFJnbkhhbmRsZSkgbmlsKTsKCiAgICAvKiBVcGRhdGUgZ3VpLmN1cnNvcl9yb3cgaWYgdGhlIGN1cnNvciBzY3JvbGxlZCBvciBjb3BpZWQgb3ZlciAqLwogICAgaWYgKGd1aS5jdXJzb3Jfcm93ID49IGd1aS5yb3cKCSAgICAmJiBndWkuY3Vyc29yX2NvbCA+PSBndWkuc2Nyb2xsX3JlZ2lvbl9sZWZ0CgkgICAgJiYgZ3VpLmN1cnNvcl9jb2wgPD0gZ3VpLnNjcm9sbF9yZWdpb25fcmlnaHQpCiAgICB7CglpZiAoZ3VpLmN1cnNvcl9yb3cgPD0gZ3VpLnNjcm9sbF9yZWdpb25fYm90IC0gbnVtX2xpbmVzKQoJICAgIGd1aS5jdXJzb3Jfcm93ICs9IG51bV9saW5lczsKCWVsc2UgaWYgKGd1aS5jdXJzb3Jfcm93IDw9IGd1aS5zY3JvbGxfcmVnaW9uX2JvdCkKCSAgICBndWkuY3Vyc29yX2lzX3ZhbGlkID0gRkFMU0U7CiAgICB9CgogICAgZ3VpX2NsZWFyX2Jsb2NrKHJvdywgZ3VpLnNjcm9sbF9yZWdpb25fbGVmdCwKCQkJCXJvdyArIG51bV9saW5lcyAtIDEsIGd1aS5zY3JvbGxfcmVnaW9uX3JpZ2h0KTsKfQoKICAgIC8qCiAgICAgKiBUT0RPOiBhZGQgYSB2aW0gZm9ybWF0IHRvIHRoZSBjbGlwYm9hcmQgd2hpY2ggcmVtZW1iZXIKICAgICAqCSAgICAgTElORVdJU0UsIENIQVJXSVNFLCBCTE9DS1dJU0UKICAgICAqLwoKICAgIHZvaWQKY2xpcF9tY2hfcmVxdWVzdF9zZWxlY3Rpb24oVmltQ2xpcGJvYXJkICpjYmQpCnsKCiAgICBIYW5kbGUJdGV4dE9mQ2xpcDsKICAgIGludAkJZmxhdm9yID0gMDsKICAgIFNpemUJc2NyYXBTaXplOwogICAgU2NyYXBGbGF2b3JGbGFncwlzY3JhcEZsYWdzOwogICAgU2NyYXBSZWYgICAgc2NyYXAgPSBuaWw7CiAgICBPU1N0YXR1cwllcnJvcjsKICAgIGludAkJdHlwZTsKICAgIGNoYXIJKnNlYXJjaENSOwogICAgY2hhcl91CSp0ZW1wY2xpcDsKCgogICAgZXJyb3IgPSBHZXRDdXJyZW50U2NyYXAoJnNjcmFwKTsKICAgIGlmIChlcnJvciAhPSBub0VycikKCXJldHVybjsKCiAgICBlcnJvciA9IEdldFNjcmFwRmxhdm9yRmxhZ3Moc2NyYXAsIFZJTVNDUkFQRkxBVk9SLCAmc2NyYXBGbGFncyk7CiAgICBpZiAoZXJyb3IgPT0gbm9FcnIpCiAgICB7CgllcnJvciA9IEdldFNjcmFwRmxhdm9yU2l6ZShzY3JhcCwgVklNU0NSQVBGTEFWT1IsICZzY3JhcFNpemUpOwoJaWYgKGVycm9yID09IG5vRXJyICYmIHNjcmFwU2l6ZSA+IDEpCgkgICAgZmxhdm9yID0gMTsKICAgIH0KCiAgICBpZiAoZmxhdm9yID09IDApCiAgICB7CgllcnJvciA9IEdldFNjcmFwRmxhdm9yRmxhZ3Moc2NyYXAsIFNDUkFQVEVYVEZMQVZPUiwgJnNjcmFwRmxhZ3MpOwoJaWYgKGVycm9yICE9IG5vRXJyKQoJICAgIHJldHVybjsKCgllcnJvciA9IEdldFNjcmFwRmxhdm9yU2l6ZShzY3JhcCwgU0NSQVBURVhURkxBVk9SLCAmc2NyYXBTaXplKTsKCWlmIChlcnJvciAhPSBub0VycikKCSAgICByZXR1cm47CiAgICB9CgogICAgUmVzZXJ2ZU1lbShzY3JhcFNpemUpOwoKICAgIC8qIEluIENBUkJPTiB3ZSBkb24ndCBuZWVkIGEgSGFuZGxlLCBhIHBvaW50ZXIgaXMgZ29vZCAqLwogICAgdGV4dE9mQ2xpcCA9IE5ld0hhbmRsZShzY3JhcFNpemUpOwoKICAgIC8qIHRlbXBjbGlwID0gbGFsbG9jKHNjcmFwU2l6ZSsxLCBUUlVFKTsgKi8KICAgIEhMb2NrKHRleHRPZkNsaXApOwogICAgZXJyb3IgPSBHZXRTY3JhcEZsYXZvckRhdGEoc2NyYXAsCgkgICAgZmxhdm9yID8gVklNU0NSQVBGTEFWT1IgOiBTQ1JBUFRFWFRGTEFWT1IsCgkgICAgJnNjcmFwU2l6ZSwgKnRleHRPZkNsaXApOwogICAgc2NyYXBTaXplIC09IGZsYXZvcjsKCiAgICBpZiAoZmxhdm9yKQoJdHlwZSA9ICoqdGV4dE9mQ2xpcDsKICAgIGVsc2UKCXR5cGUgPSAoc3RyY2hyKCp0ZXh0T2ZDbGlwLCAnXHInKSAhPSBOVUxMKSA/IE1MSU5FIDogTUNIQVI7CgogICAgdGVtcGNsaXAgPSBsYWxsb2Moc2NyYXBTaXplICsgMSwgVFJVRSk7CiAgICBtY2hfbWVtbW92ZSh0ZW1wY2xpcCwgKnRleHRPZkNsaXAgKyBmbGF2b3IsIHNjcmFwU2l6ZSk7CiAgICB0ZW1wY2xpcFtzY3JhcFNpemVdID0gMDsKCiNpZmRlZiBNQUNPU19DT05WRVJUCiAgICB7CgkvKiBDb252ZXJ0IGZyb20gdXRmLTE2IChjbGlwYm9hcmQpICovCglzaXplX3QgZW5jTGVuID0gMDsKCWNoYXJfdSAqdG8gPSBtYWNfdXRmMTZfdG9fZW5jKChVbmlDaGFyICopdGVtcGNsaXAsIHNjcmFwU2l6ZSwgJmVuY0xlbik7CgoJaWYgKHRvICE9IE5VTEwpCgl7CgkgICAgc2NyYXBTaXplID0gZW5jTGVuOwoJICAgIHZpbV9mcmVlKHRlbXBjbGlwKTsKCSAgICB0ZW1wY2xpcCA9IHRvOwoJfQogICAgfQojZW5kaWYKCiAgICBzZWFyY2hDUiA9IChjaGFyICopdGVtcGNsaXA7CiAgICB3aGlsZSAoc2VhcmNoQ1IgIT0gTlVMTCkKICAgIHsKCXNlYXJjaENSID0gc3RyY2hyKHNlYXJjaENSLCAnXHInKTsKCWlmIChzZWFyY2hDUiAhPSBOVUxMKQoJICAgICpzZWFyY2hDUiA9ICdcbic7CiAgICB9CgogICAgY2xpcF95YW5rX3NlbGVjdGlvbih0eXBlLCB0ZW1wY2xpcCwgc2NyYXBTaXplLCBjYmQpOwoKICAgIHZpbV9mcmVlKHRlbXBjbGlwKTsKICAgIEhVbmxvY2sodGV4dE9mQ2xpcCk7CgogICAgRGlzcG9zZUhhbmRsZSh0ZXh0T2ZDbGlwKTsKfQoKICAgIHZvaWQKY2xpcF9tY2hfbG9zZV9zZWxlY3Rpb24oVmltQ2xpcGJvYXJkICpjYmQpCnsKICAgIC8qCiAgICAgKiBUT0RPOiBSZWFsbHkgbm90aGluZyB0byBkbz8KICAgICAqLwp9CgogICAgaW50CmNsaXBfbWNoX293bl9zZWxlY3Rpb24oVmltQ2xpcGJvYXJkICpjYmQpCnsKICAgIHJldHVybiBPSzsKfQoKLyoKICogU2VuZCB0aGUgY3VycmVudCBzZWxlY3Rpb24gdG8gdGhlIGNsaXBib2FyZC4KICovCiAgICB2b2lkCmNsaXBfbWNoX3NldF9zZWxlY3Rpb24oVmltQ2xpcGJvYXJkICpjYmQpCnsKICAgIEhhbmRsZQl0ZXh0T2ZDbGlwOwogICAgbG9uZwlzY3JhcFNpemU7CiAgICBpbnQJCXR5cGU7CiAgICBTY3JhcFJlZiAgICBzY3JhcDsKCiAgICBjaGFyX3UJKnN0ciA9IE5VTEw7CgogICAgaWYgKCFjYmQtPm93bmVkKQoJcmV0dXJuOwoKICAgIGNsaXBfZ2V0X3NlbGVjdGlvbihjYmQpOwoKICAgIC8qCiAgICAgKiBPbmNlIHdlIHNldCB0aGUgY2xpcGJvYXJkLCBsb3NlIG93bmVyc2hpcC4gIElmIGFub3RoZXIgYXBwbGljYXRpb24gc2V0cwogICAgICogdGhlIGNsaXBib2FyZCwgd2UgZG9uJ3Qgd2FudCB0byB0aGluayB0aGF0IHdlIHN0aWxsIG93biBpdC4KICAgICAqLwogICAgY2JkLT5vd25lZCA9IEZBTFNFOwoKICAgIHR5cGUgPSBjbGlwX2NvbnZlcnRfc2VsZWN0aW9uKCZzdHIsIChsb25nX3UgKikmc2NyYXBTaXplLCBjYmQpOwoKI2lmZGVmIE1BQ09TX0NPTlZFUlQKICAgIHNpemVfdCB1dGYxNl9sZW4gPSAwOwogICAgVW5pQ2hhciAqdG8gPSBtYWNfZW5jX3RvX3V0ZjE2KHN0ciwgc2NyYXBTaXplLCAmdXRmMTZfbGVuKTsKICAgIGlmICh0bykKICAgIHsKCXNjcmFwU2l6ZSA9IHV0ZjE2X2xlbjsKCXZpbV9mcmVlKHN0cik7CglzdHIgPSAoY2hhcl91ICopdG87CiAgICB9CiNlbmRpZgoKICAgIGlmICh0eXBlID49IDApCiAgICB7CglDbGVhckN1cnJlbnRTY3JhcCgpOwoKCXRleHRPZkNsaXAgPSBOZXdIYW5kbGUoc2NyYXBTaXplICsgMSk7CglITG9jayh0ZXh0T2ZDbGlwKTsKCgkqKnRleHRPZkNsaXAgPSB0eXBlOwoJbWNoX21lbW1vdmUoKnRleHRPZkNsaXAgKyAxLCBzdHIsIHNjcmFwU2l6ZSk7CglHZXRDdXJyZW50U2NyYXAoJnNjcmFwKTsKCVB1dFNjcmFwRmxhdm9yKHNjcmFwLCBTQ1JBUFRFWFRGTEFWT1IsIGtTY3JhcEZsYXZvck1hc2tOb25lLAoJCXNjcmFwU2l6ZSwgKnRleHRPZkNsaXAgKyAxKTsKCVB1dFNjcmFwRmxhdm9yKHNjcmFwLCBWSU1TQ1JBUEZMQVZPUiwga1NjcmFwRmxhdm9yTWFza05vbmUsCgkJc2NyYXBTaXplICsgMSwgKnRleHRPZkNsaXApOwoJSFVubG9jayh0ZXh0T2ZDbGlwKTsKCURpc3Bvc2VIYW5kbGUodGV4dE9mQ2xpcCk7CiAgICB9CgogICAgdmltX2ZyZWUoc3RyKTsKfQoKICAgIHZvaWQKZ3VpX21jaF9zZXRfdGV4dF9hcmVhX3BvcyhpbnQgeCwgaW50IHksIGludCB3LCBpbnQgaCkKewogICAgUmVjdAlWaW1Cb3VuZDsKCi8qICBIaWRlV2luZG93KGd1aS5WaW1XaW5kb3cpOyAqLwogICAgR2V0V2luZG93Qm91bmRzKGd1aS5WaW1XaW5kb3csIGtXaW5kb3dHbG9iYWxQb3J0UmduLCAmVmltQm91bmQpOwoKICAgIGlmIChndWkud2hpY2hfc2Nyb2xsYmFyc1tTQkFSX0xFRlRdKQogICAgewoJVmltQm91bmQubGVmdCA9IC1ndWkuc2Nyb2xsYmFyX3dpZHRoICsgMTsKICAgIH0KICAgIGVsc2UKICAgIHsKCVZpbUJvdW5kLmxlZnQgPSAwOwogICAgfQoKICAgIFNldFdpbmRvd0JvdW5kcyhndWkuVmltV2luZG93LCBrV2luZG93R2xvYmFsUG9ydFJnbiwgJlZpbUJvdW5kKTsKCiAgICBTaG93V2luZG93KGd1aS5WaW1XaW5kb3cpOwp9CgovKgogKiBNZW51IHN0dWZmLgogKi8KCiAgICB2b2lkCmd1aV9tY2hfZW5hYmxlX21lbnUoaW50IGZsYWcpCnsKICAgIC8qCiAgICAgKiBNZW51IGlzIGFsd2F5cyBhY3RpdmUuCiAgICAgKi8KfQoKICAgIHZvaWQKZ3VpX21jaF9zZXRfbWVudV9wb3MoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpCnsKICAgIC8qCiAgICAgKiBUaGUgbWVudSBpcyBhbHdheXMgYXQgdGhlIHRvcCBvZiB0aGUgc2NyZWVuLgogICAgICovCn0KCi8qCiAqIEFkZCBhIHN1YiBtZW51IHRvIHRoZSBtZW51IGJhci4KICovCiAgICB2b2lkCmd1aV9tY2hfYWRkX21lbnUodmltbWVudV9UICptZW51LCBpbnQgaWR4KQp7CiAgICAvKgogICAgICogVE9ETzogVHJ5IHRvIHVzZSBvbmx5IG1lbnVfaWQgaW5zdGVhZCBvZiBib3RoIG1lbnVfaWQgYW5kIG1lbnVfaGFuZGxlLgogICAgICogVE9ETzogdXNlIG1lbnUtPm1uZW1vbmljIGFuZCBtZW51LT5hY3RleHQKICAgICAqIFRPRE86IFRyeSB0byByZXVzZSBtZW51IGlkCiAgICAgKiAgICAgICBDYXJib24gSGVscCBzdWdnZXN0IHRvIHVzZSBvbmx5IGlkIGJldHdlZW4gMSBhbmQgMjM1CiAgICAgKi8KICAgIHN0YXRpYyBsb25nCSBuZXh0X2F2YWlsX2lkID0gMTI4OwogICAgbG9uZwkgbWVudV9hZnRlcl9tZSA9IDA7IC8qIERlZmF1bHQgdG8gdGhlIGVuZCAqLwojaWYgZGVmaW5lZChGRUFUX01CWVRFKQogICAgQ0ZTdHJpbmdSZWYgbmFtZTsKI2Vsc2UKICAgIGNoYXJfdQkqbmFtZTsKI2VuZGlmCiAgICBzaG9ydAkgaW5kZXg7CiAgICB2aW1tZW51X1QJKnBhcmVudCA9IG1lbnUtPnBhcmVudDsKICAgIHZpbW1lbnVfVAkqYnJvdGhlciA9IG1lbnUtPm5leHQ7CgogICAgLyogQ2Fubm90IGFkZCBhIG1lbnUgaWYgLi4uICovCiAgICBpZiAoKHBhcmVudCAhPSBOVUxMICYmIHBhcmVudC0+c3VibWVudV9pZCA9PSAwKSkKCXJldHVybjsKCiAgICAvKiBtZW51IElEIGdyZWF0ZXIgdGhhbiAxMDI0IGFyZSByZXNlcnZlZCBmb3IgPz8/ICovCiAgICBpZiAobmV4dF9hdmFpbF9pZCA9PSAxMDI0KQoJcmV0dXJuOwoKICAgIC8qIE15IGJyb3RoZXIgY291bGQgYmUgdGhlIFBvcFVwLCBmaW5kIG15IHJlYWwgYnJvdGhlciAqLwogICAgd2hpbGUgKChicm90aGVyICE9IE5VTEwpICYmICghbWVudV9pc19tZW51YmFyKGJyb3RoZXItPm5hbWUpKSkKCWJyb3RoZXIgPSBicm90aGVyLT5uZXh0OwoKICAgIC8qICBGaW5kIHdoZXJlIHRvIGluc2VydCB0aGUgbWVudSAoZm9yIE1lbnVCYXIpICovCiAgICBpZiAoKHBhcmVudCA9PSBOVUxMKSAmJiAoYnJvdGhlciAhPSBOVUxMKSkKCW1lbnVfYWZ0ZXJfbWUgPSBicm90aGVyLT5zdWJtZW51X2lkOwoKICAgIC8qIElmIHRoZSBtZW51IGlzIG5vdCBwYXJ0IG9mIHRoZSBtZW51YmFyIChhbmQgaXRzIHN1Ym1lbnVzKSwgYWRkIGl0ICdub3doZXJlJyAqLwogICAgaWYgKCFtZW51X2lzX21lbnViYXIobWVudS0+bmFtZSkpCgltZW51X2FmdGVyX21lID0gaGllck1lbnU7CgogICAgLyogQ29udmVydCB0aGUgbmFtZSAqLwojaWZkZWYgTUFDT1NfQ09OVkVSVAogICAgbmFtZSA9IG1lbnVfdGl0bGVfcmVtb3ZpbmdfbW5lbW9uaWMobWVudSk7CiNlbHNlCiAgICBuYW1lID0gQzJQYXNjYWxfc2F2ZShtZW51LT5kbmFtZSk7CiNlbmRpZgogICAgaWYgKG5hbWUgPT0gTlVMTCkKCXJldHVybjsKCiAgICAvKiBDcmVhdGUgdGhlIG1lbnUgdW5sZXNzIGl0J3MgdGhlIGhlbHAgbWVudSAqLwogICAgewoJLyogQ2FyYm9uIHN1Z2dlc3QgdXNlIG9mCgkgKiBPU1N0YXR1cyBDcmVhdGVOZXdNZW51KE1lbnVJRCwgTWVudUF0dHJpYnV0ZXMsIE1lbnVSZWYgKik7CgkgKiBPU1N0YXR1cyBTZXRNZW51VGl0bGUoTWVudVJlZiwgQ29uc3RTdHIyNTVQYXJhbSB0aXRsZSk7CgkgKi8KCW1lbnUtPnN1Ym1lbnVfaWQgPSBuZXh0X2F2YWlsX2lkOwojaWYgZGVmaW5lZChGRUFUX01CWVRFKQoJaWYgKENyZWF0ZU5ld01lbnUobWVudS0+c3VibWVudV9pZCwgMCwgKE1lbnVSZWYgKikmbWVudS0+c3VibWVudV9oYW5kbGUpID09IG5vRXJyKQoJICAgIFNldE1lbnVUaXRsZVdpdGhDRlN0cmluZygoTWVudVJlZiltZW51LT5zdWJtZW51X2hhbmRsZSwgbmFtZSk7CiNlbHNlCgltZW51LT5zdWJtZW51X2hhbmRsZSA9IE5ld01lbnUobWVudS0+c3VibWVudV9pZCwgbmFtZSk7CiNlbmRpZgoJbmV4dF9hdmFpbF9pZCsrOwogICAgfQoKICAgIGlmIChwYXJlbnQgPT0gTlVMTCkKICAgIHsKCS8qIEFkZGluZyBhIG1lbnUgdG8gdGhlIG1lbnViYXIsIG9yIGluIHRoZSBubyBtYW5zIGxhbmQgKGZvciBQb3BVcCkgKi8KCgkvKiBUT0RPOiBWZXJpZnkgaWYgd2UgY291bGQgb25seSBJbnNlcnQgTWVudSBpZiByZWFsbHkgcGFydCBvZiB0aGUKCSAqIG1lbnViYXIgVGhlIEluc2VydGVkIG1lbnUgYXJlIHNjYW5uZWQgb3IgdGhlIENvbW1hbmQta2V5IGNvbWJvcwoJICovCgoJLyogSW5zZXJ0IHRoZSBtZW51ICovCglJbnNlcnRNZW51KG1lbnUtPnN1Ym1lbnVfaGFuZGxlLCBtZW51X2FmdGVyX21lKTsgLyogaW5zZXJ0IGJlZm9yZSAqLwojaWYgMQoJLyogVmltIHNob3VsZCBub3JtYWxseSB1cGRhdGUgaXQuIFRPRE86IHZlcmlmeSAqLwoJRHJhd01lbnVCYXIoKTsKI2VuZGlmCiAgICB9CiAgICBlbHNlCiAgICB7CgkvKiBBZGRpbmcgYXMgYSBzdWJtZW51ICovCgoJaW5kZXggPSBndWlfbWFjX2dldF9tZW51X2l0ZW1faW5kZXgobWVudSk7CgoJLyogQ2FsbCBJbnNlcnRNZW51SXRlbSBmb2xsb3dlZCBieSBTZXRNZW51SXRlbVRleHQKCSAqIHRvIGF2b2lkIHNwZWNpYWwgY2hhcmFjdGVyIHJlY29nbml0aW9uIGJ5IEluc2VydE1lbnVJdGVtCgkgKi8KCUluc2VydE1lbnVJdGVtKHBhcmVudC0+c3VibWVudV9oYW5kbGUsICJccCAiLCBpZHgpOyAvKiBhZnRlckl0ZW0gKi8KI2lmIGRlZmluZWQoRkVBVF9NQllURSkKCVNldE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZyhwYXJlbnQtPnN1Ym1lbnVfaGFuZGxlLCBpZHgrMSwgbmFtZSk7CiNlbHNlCglTZXRNZW51SXRlbVRleHQocGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaWR4KzEsIG5hbWUpOwojZW5kaWYKCVNldEl0ZW1DbWQocGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaWR4KzEsIDB4MUIpOwoJU2V0SXRlbU1hcmsocGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaWR4KzEsIG1lbnUtPnN1Ym1lbnVfaWQpOwoJSW5zZXJ0TWVudShtZW51LT5zdWJtZW51X2hhbmRsZSwgaGllck1lbnUpOwogICAgfQoKI2lmIGRlZmluZWQoRkVBVF9NQllURSkKICAgIENGUmVsZWFzZShuYW1lKTsKI2Vsc2UKICAgIHZpbV9mcmVlKG5hbWUpOwojZW5kaWYKCiNpZiAwCiAgICAvKiBEb25lIGJ5IFZpbSBsYXRlciBvbiAqLwogICAgRHJhd01lbnVCYXIoKTsKI2VuZGlmCn0KCi8qCiAqIEFkZCBhIG1lbnUgaXRlbSB0byBhIG1lbnUKICovCiAgICB2b2lkCmd1aV9tY2hfYWRkX21lbnVfaXRlbSh2aW1tZW51X1QgKm1lbnUsIGludCBpZHgpCnsKI2lmIGRlZmluZWQoRkVBVF9NQllURSkKICAgIENGU3RyaW5nUmVmIG5hbWU7CiNlbHNlCiAgICBjaGFyX3UJKm5hbWU7CiNlbmRpZgogICAgdmltbWVudV9UCSpwYXJlbnQgPSBtZW51LT5wYXJlbnQ7CiAgICBpbnQJCW1lbnVfaW5zZXJ0ZWQ7CgogICAgLyogQ2Fubm90IGFkZCBpdGVtLCBpZiB0aGUgbWVudSBoYXZlIG5vdCBiZWVuIGNyZWF0ZWQgKi8KICAgIGlmIChwYXJlbnQtPnN1Ym1lbnVfaWQgPT0gMCkKCXJldHVybjsKCiAgICAvKiBDb3VsZCBjYWxsIFNldE1lbnVSZWZDb24gW0NBUkJPTl0gdG8gYXNzb2NpYXRlIHdpdGggdGhlIE1lbnUsCiAgICAgICBmb3Igb2xkZXIgT1MgY2FsbCBHZXRNZW51SXRlbURhdGEgKG1lbnUsIGl0ZW0sIGlzQ29tbWFuZElEPywgZGF0YSkgKi8KCiAgICAvKiBDb252ZXJ0IHRoZSBuYW1lICovCiNpZmRlZiBNQUNPU19DT05WRVJUCiAgICBuYW1lID0gbWVudV90aXRsZV9yZW1vdmluZ19tbmVtb25pYyhtZW51KTsKI2Vsc2UKICAgIG5hbWUgPSBDMlBhc2NhbF9zYXZlKG1lbnUtPmRuYW1lKTsKI2VuZGlmCgogICAgLyogV2hlcmUgYXJlIGp1c3QgYSBtZW51IGl0ZW0sIHNvIG5vIGhhbmRsZSwgbm8gaWQgKi8KICAgIG1lbnUtPnN1Ym1lbnVfaWQgPSAwOwogICAgbWVudS0+c3VibWVudV9oYW5kbGUgPSBOVUxMOwoKICAgIG1lbnVfaW5zZXJ0ZWQgPSAwOwogICAgaWYgKG1lbnUtPmFjdGV4dCkKICAgIHsKCS8qIElmIHRoZSBhY2NlbGVyYXRvciB0ZXh0IGZvciB0aGUgbWVudSBpdGVtIGxvb2tzIGxpa2UgaXQgZGVzY3JpYmVzCgkgKiBhIGNvbW1hbmQga2V5IChlLmcuLCAiPEQtUy10PiIgb3IgIjxDLTc+IiksIGRpc3BsYXkgaXQgYXMgdGhlCgkgKiBpdGVtJ3MgY29tbWFuZCBlcXVpdmFsZW50LgoJICovCglpbnQJICAgIGtleSA9IDA7CglpbnQJICAgIG1vZGlmaWVycyA9IDA7CgljaGFyX3UJICAgICpwX2FjdGV4dDsKCglwX2FjdGV4dCA9IG1lbnUtPmFjdGV4dDsKCWtleSA9IGZpbmRfc3BlY2lhbF9rZXkoJnBfYWN0ZXh0LCAmbW9kaWZpZXJzLCAvKmtleWNvZGU9Ki8wKTsKCWlmICgqcF9hY3RleHQgIT0gMCkKCSAgICBrZXkgPSAwOyAvKiBlcnJvcjogdHJhaWxpbmcgdGV4dCAqLwoJLyogZmluZF9zcGVjaWFsX2tleSgpIHJldHVybnMgYSBrZXljb2RlIHdpdGggYXMgbWFueSBvZiB0aGUKCSAqIHNwZWNpZmllZCBtb2RpZmllcnMgYXMgYXBwcm9wcmlhdGUgYWxyZWFkeSBhcHBsaWVkIChlLmcuLCBmb3IKCSAqICI8RC1DLXg+IiBpdCByZXR1cm5zIEN0cmwtWCBhcyB0aGUga2V5Y29kZSBhbmQgTU9EX01BU0tfQ01ECgkgKiBhcyB0aGUgb25seSBtb2RpZmllcikuICBTaW5jZSB3ZSB3YW50IHRvIGRpc3BsYXkgYWxsIG9mIHRoZQoJICogbW9kaWZpZXJzLCB3ZSBuZWVkIHRvIGNvbnZlcnQgdGhlIGtleWNvZGUgYmFjayB0byBhIHByaW50YWJsZQoJICogY2hhcmFjdGVyIHBsdXMgbW9kaWZpZXJzLgoJICogVE9ETzogV3JpdGUgYW4gYWx0ZXJuYXRpdmUgZmluZF9zcGVjaWFsX2tleSgpIHRoYXQgZG9lc24ndAoJICogYXBwbHkgbW9kaWZpZXJzLgoJICovCglpZiAoa2V5ID4gMCAmJiBrZXkgPCAzMikKCXsKCSAgICAvKiBDb252ZXJ0IGEgY29udHJvbCBrZXkgdG8gYW4gdXBwZXJjYXNlIGxldHRlci4gIE5vdGUgdGhhdAoJICAgICAqIGJ5IHRoaXMgcG9pbnQgaXQgaXMgbm8gbG9uZ2VyIHBvc3NpYmxlIHRvIGRpc3Rpbmd1aXNoCgkgICAgICogYmV0d2VlbiwgZS5nLiwgQ3RybC1TIGFuZCBDdHJsLVNoaWZ0LVMuCgkgICAgICovCgkgICAgbW9kaWZpZXJzIHw9IE1PRF9NQVNLX0NUUkw7CgkgICAga2V5ICs9ICdAJzsKCX0KCS8qIElmIHRoZSBrZXljb2RlIGlzIGFuIHVwcGVyY2FzZSBsZXR0ZXIsIHNldCB0aGUgU2hpZnQgbW9kaWZpZXIuCgkgKiBJZiBpdCBpcyBhIGxvd2VyY2FzZSBsZXR0ZXIsIGRvbid0IHNldCB0aGUgbW9kaWZpZXIsIGJ1dCBjb252ZXJ0CgkgKiB0aGUgbGV0dGVyIHRvIHVwcGVyY2FzZSBmb3IgZGlzcGxheSBpbiB0aGUgbWVudS4KCSAqLwoJZWxzZSBpZiAoa2V5ID49ICdBJyAmJiBrZXkgPD0gJ1onKQoJICAgIG1vZGlmaWVycyB8PSBNT0RfTUFTS19TSElGVDsKCWVsc2UgaWYgKGtleSA+PSAnYScgJiYga2V5IDw9ICd6JykKCSAgICBrZXkgKz0gJ0EnIC0gJ2EnOwoJLyogTm90ZToga2V5Y29kZXMgYmVsb3cgMHgyMiBhcmUgcmVzZXJ2ZWQgYnkgQXBwbGUuICovCglpZiAoa2V5ID49IDB4MjIgJiYgdmltX2lzcHJpbnRjX3N0cmljdChrZXkpKQoJewoJICAgIGludAkJdmFsaWQgPSAxOwoJICAgIGNoYXJfdSAgICAgIG1hY19tb2RzID0ga01lbnVOb01vZGlmaWVyczsKCSAgICAvKiBDb252ZXJ0IFZpbSBtb2RpZmllciBjb2RlcyB0byBNZW51IE1hbmFnZXIgZXF1aXZhbGVudHMuICovCgkgICAgaWYgKG1vZGlmaWVycyAmIE1PRF9NQVNLX1NISUZUKQoJCW1hY19tb2RzIHw9IGtNZW51U2hpZnRNb2RpZmllcjsKCSAgICBpZiAobW9kaWZpZXJzICYgTU9EX01BU0tfQ1RSTCkKCQltYWNfbW9kcyB8PSBrTWVudUNvbnRyb2xNb2RpZmllcjsKCSAgICBpZiAoIShtb2RpZmllcnMgJiBNT0RfTUFTS19DTUQpKQoJCW1hY19tb2RzIHw9IGtNZW51Tm9Db21tYW5kTW9kaWZpZXI7CgkgICAgaWYgKG1vZGlmaWVycyAmIE1PRF9NQVNLX0FMVCB8fCBtb2RpZmllcnMgJiBNT0RfTUFTS19NVUxUSV9DTElDSykKCQl2YWxpZCA9IDA7IC8qIFRPRE86IHdpbGwgQWx0IHNvbWVkYXkgbWFwIHRvIE9wdGlvbj8gKi8KCSAgICBpZiAodmFsaWQpCgkgICAgewoJCWNoYXJfdQkgICAgaXRlbV90eHRbMTBdOwoJCS8qIEluc2VydCB0aGUgbWVudSBpdGVtIGFmdGVyIGlkeCwgd2l0aCBpdHMgY29tbWFuZCBrZXkuICovCgkJaXRlbV90eHRbMF0gPSAzOyBpdGVtX3R4dFsxXSA9ICcgJzsgaXRlbV90eHRbMl0gPSAnLyc7CgkJaXRlbV90eHRbM10gPSBrZXk7CgkJSW5zZXJ0TWVudUl0ZW0ocGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaXRlbV90eHQsIGlkeCk7CgkJLyogU2V0IHRoZSBtb2RpZmllciBrZXlzLiAqLwoJCVNldE1lbnVJdGVtTW9kaWZpZXJzKHBhcmVudC0+c3VibWVudV9oYW5kbGUsIGlkeCsxLCBtYWNfbW9kcyk7CgkJbWVudV9pbnNlcnRlZCA9IDE7CgkgICAgfQoJfQogICAgfQogICAgLyogQ2FsbCBJbnNlcnRNZW51SXRlbSBmb2xsb3dlZCBieSBTZXRNZW51SXRlbVRleHQKICAgICAqIHRvIGF2b2lkIHNwZWNpYWwgY2hhcmFjdGVyIHJlY29nbml0aW9uIGJ5IEluc2VydE1lbnVJdGVtCiAgICAgKi8KICAgIGlmICghbWVudV9pbnNlcnRlZCkKCUluc2VydE1lbnVJdGVtKHBhcmVudC0+c3VibWVudV9oYW5kbGUsICJccCAiLCBpZHgpOyAvKiBhZnRlckl0ZW0gKi8KICAgIC8qIFNldCB0aGUgbWVudSBpdGVtIG5hbWUuICovCiNpZiBkZWZpbmVkKEZFQVRfTUJZVEUpCiAgICBTZXRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcocGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaWR4KzEsIG5hbWUpOwojZWxzZQogICAgU2V0TWVudUl0ZW1UZXh0KHBhcmVudC0+c3VibWVudV9oYW5kbGUsIGlkeCsxLCBuYW1lKTsKI2VuZGlmCgojaWYgMAogICAgLyogQ2FsbGVkIGJ5IFZpbSAqLwogICAgRHJhd01lbnVCYXIoKTsKI2VuZGlmCgojaWYgZGVmaW5lZChGRUFUX01CWVRFKQogICAgQ0ZSZWxlYXNlKG5hbWUpOwojZWxzZQogICAgLyogVE9ETzogQ2FuIG5hbWUgYmUgZnJlZWQ/ICovCiAgICB2aW1fZnJlZShuYW1lKTsKI2VuZGlmCn0KCiAgICB2b2lkCmd1aV9tY2hfdG9nZ2xlX3RlYXJvZmZzKGludCBlbmFibGUpCnsKICAgIC8qIG5vIHRlYXJvZmYgbWVudXMgKi8KfQoKLyoKICogRGVzdHJveSB0aGUgbWFjaGluZSBzcGVjaWZpYyBtZW51IHdpZGdldC4KICovCiAgICB2b2lkCmd1aV9tY2hfZGVzdHJveV9tZW51KHZpbW1lbnVfVCAqbWVudSkKewogICAgc2hvcnQJaW5kZXggPSBndWlfbWFjX2dldF9tZW51X2l0ZW1faW5kZXgobWVudSk7CgogICAgaWYgKGluZGV4ID4gMCkKICAgIHsKICAgICAgaWYgKG1lbnUtPnBhcmVudCkKICAgICAgewoJewoJICAgIC8qIEZvciBub3cganVzdCBkb24ndCBkZWxldGUgaGVscCBtZW51IGl0ZW1zLiAoSHVoPyBEYW55KSAqLwoJICAgIERlbGV0ZU1lbnVJdGVtKG1lbnUtPnBhcmVudC0+c3VibWVudV9oYW5kbGUsIGluZGV4KTsKCgkgICAgLyogRGVsZXRlIHRoZSBNZW51IGlmIGl0IHdhcyBhIGhpZXJhcmNoaWNhbCBNZW51ICovCgkgICAgaWYgKG1lbnUtPnN1Ym1lbnVfaWQgIT0gMCkKCSAgICB7CgkJRGVsZXRlTWVudShtZW51LT5zdWJtZW51X2lkKTsKCQlEaXNwb3NlTWVudShtZW51LT5zdWJtZW51X2hhbmRsZSk7CgkgICAgfQoJfQogICAgICB9CiNpZmRlZiBERUJVR19NQUNfTUVOVQogICAgICBlbHNlCiAgICAgIHsKCXByaW50ZigiZ21kbSAyXG4iKTsKICAgICAgfQojZW5kaWYKICAgIH0KICAgIGVsc2UKICAgIHsKCXsKCSAgICBEZWxldGVNZW51KG1lbnUtPnN1Ym1lbnVfaWQpOwoJICAgIERpc3Bvc2VNZW51KG1lbnUtPnN1Ym1lbnVfaGFuZGxlKTsKCX0KICAgIH0KICAgIC8qIFNob3VsZG4ndCB0aGlzIGJlIGFscmVhZHkgZG9uZSBieSBWaW0uIFRPRE86IENoZWNrICovCiAgICBEcmF3TWVudUJhcigpOwp9CgovKgogKiBNYWtlIGEgbWVudSBlaXRoZXIgZ3JleSBvciBub3QgZ3JleS4KICovCiAgICB2b2lkCmd1aV9tY2hfbWVudV9ncmV5KHZpbW1lbnVfVCAqbWVudSwgaW50IGdyZXkpCnsKICAgIC8qIFRPRE86IENoZWNrIGlmIG1lbnUgcmVhbGx5IGV4aXN0cyAqLwogICAgc2hvcnQgaW5kZXggPSBndWlfbWFjX2dldF9tZW51X2l0ZW1faW5kZXgobWVudSk7Ci8qCiAgICBpbmRleCA9IG1lbnUtPmluZGV4OwoqLwogICAgaWYgKGdyZXkpCiAgICB7CglpZiAobWVudS0+Y2hpbGRyZW4pCgkgICAgRGlzYWJsZU1lbnVJdGVtKG1lbnUtPnN1Ym1lbnVfaGFuZGxlLCBpbmRleCk7CglpZiAobWVudS0+cGFyZW50KQoJICBpZiAobWVudS0+cGFyZW50LT5zdWJtZW51X2hhbmRsZSkKCSAgICBEaXNhYmxlTWVudUl0ZW0obWVudS0+cGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaW5kZXgpOwogICAgfQogICAgZWxzZQogICAgewoJaWYgKG1lbnUtPmNoaWxkcmVuKQoJICAgIEVuYWJsZU1lbnVJdGVtKG1lbnUtPnN1Ym1lbnVfaGFuZGxlLCBpbmRleCk7CglpZiAobWVudS0+cGFyZW50KQoJICBpZiAobWVudS0+cGFyZW50LT5zdWJtZW51X2hhbmRsZSkKCSAgICBFbmFibGVNZW51SXRlbShtZW51LT5wYXJlbnQtPnN1Ym1lbnVfaGFuZGxlLCBpbmRleCk7CiAgICB9Cn0KCi8qCiAqIE1ha2UgbWVudSBpdGVtIGhpZGRlbiBvciBub3QgaGlkZGVuCiAqLwogICAgdm9pZApndWlfbWNoX21lbnVfaGlkZGVuKHZpbW1lbnVfVCAqbWVudSwgaW50IGhpZGRlbikKewogICAgLyogVGhlcmUncyBubyBoaWRkZW4gbW9kZSBvbiBNYWNPUyAqLwogICAgZ3VpX21jaF9tZW51X2dyZXkobWVudSwgaGlkZGVuKTsKfQoKCi8qCiAqIFRoaXMgaXMgY2FsbGVkIGFmdGVyIHNldHRpbmcgYWxsIHRoZSBtZW51cyB0byBncmV5L2hpZGRlbiBvciBub3QuCiAqLwogICAgdm9pZApndWlfbWNoX2RyYXdfbWVudWJhcih2b2lkKQp7CiAgICBEcmF3TWVudUJhcigpOwp9CgoKLyoKICogU2Nyb2xsYmFyIHN0dWZmLgogKi8KCiAgICB2b2lkCmd1aV9tY2hfZW5hYmxlX3Njcm9sbGJhcigKCXNjcm9sbGJhcl9UCSpzYiwKCWludAkJZmxhZykKewogICAgaWYgKGZsYWcpCglTaG93Q29udHJvbChzYi0+aWQpOwogICAgZWxzZQoJSGlkZUNvbnRyb2woc2ItPmlkKTsKCiNpZmRlZiBERUJVR19NQUNfU0IKICAgIHByaW50ZigiZW5iX3NiICgleCkgJXhcbiIsc2ItPmlkLCBmbGFnKTsKI2VuZGlmCn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0X3Njcm9sbGJhcl90aHVtYigKCXNjcm9sbGJhcl9UICpzYiwKCWxvbmcgdmFsLAoJbG9uZyBzaXplLAoJbG9uZyBtYXgpCnsKICAgIFNldENvbnRyb2wzMkJpdE1heGltdW0gKHNiLT5pZCwgbWF4KTsKICAgIFNldENvbnRyb2wzMkJpdE1pbmltdW0gKHNiLT5pZCwgMCk7CiAgICBTZXRDb250cm9sMzJCaXRWYWx1ZSAgIChzYi0+aWQsIHZhbCk7CiNpZmRlZiBERUJVR19NQUNfU0IKICAgIHByaW50ZigidGh1bWJfc2IgKCV4KSAleCwgJXgsJXhcbiIsc2ItPmlkLCB2YWwsIHNpemUsIG1heCk7CiNlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX3NldF9zY3JvbGxiYXJfcG9zKAoJc2Nyb2xsYmFyX1QgKnNiLAoJaW50IHgsCglpbnQgeSwKCWludCB3LAoJaW50IGgpCnsKICAgIGd1aV9tY2hfc2V0X2JnX2NvbG9yKGd1aS5iYWNrX3BpeGVsKTsKLyogIGlmIChndWkud2hpY2hfc2Nyb2xsYmFyc1tTQkFSX0xFRlRdKQogICAgewoJTW92ZUNvbnRyb2woc2ItPmlkLCB4LTE2LCB5KTsKCVNpemVDb250cm9sKHNiLT5pZCwgdyArIDEsIGgpOwogICAgfQogICAgZWxzZQogICAgewoJTW92ZUNvbnRyb2woc2ItPmlkLCB4LCB5KTsKCVNpemVDb250cm9sKHNiLT5pZCwgdyArIDEsIGgpOwogICAgfSovCiAgICBpZiAoc2IgPT0gJmd1aS5ib3R0b21fc2JhcikKCWggKz0gMTsKICAgIGVsc2UKCXcgKz0gMTsKCiAgICBpZiAoZ3VpLndoaWNoX3Njcm9sbGJhcnNbU0JBUl9MRUZUXSkKCXggLT0gMTU7CgogICAgTW92ZUNvbnRyb2woc2ItPmlkLCB4LCB5KTsKICAgIFNpemVDb250cm9sKHNiLT5pZCwgdywgaCk7CiNpZmRlZiBERUJVR19NQUNfU0IKICAgIHByaW50Zigic2l6ZV9zYiAoJXgpICV4LCAleCwgJXgsICV4XG4iLHNiLT5pZCwgeCwgeSwgdywgaCk7CiNlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX2NyZWF0ZV9zY3JvbGxiYXIoCglzY3JvbGxiYXJfVCAqc2IsCglpbnQgb3JpZW50KQkvKiBTQkFSX1ZFUlQgb3IgU0JBUl9IT1JJWiAqLwp7CiAgICBSZWN0IGJvdW5kczsKCiAgICBib3VuZHMudG9wID0gLTE2OwogICAgYm91bmRzLmJvdHRvbSA9IC0xMDsKICAgIGJvdW5kcy5yaWdodCA9IC0xMDsKICAgIGJvdW5kcy5sZWZ0ID0gLTE2OwoKICAgIHNiLT5pZCA9IE5ld0NvbnRyb2woZ3VpLlZpbVdpbmRvdywKCQkJICZib3VuZHMsCgkJCSAiXHBTY3JvbGxCYXIiLAoJCQkgVFJVRSwKCQkJIDAsIC8qIGN1cnJlbnQqLwoJCQkgMCwgLyogdG9wICovCgkJCSAwLCAvKiBib3R0b20gKi8KCQkJIGtDb250cm9sU2Nyb2xsQmFyTGl2ZVByb2MsCgkJCSAobG9uZykgc2ItPmlkZW50KTsKI2lmZGVmIERFQlVHX01BQ19TQgogICAgcHJpbnRmKCJjcmVhdGVfc2IgKCV4KSAleFxuIixzYi0+aWQsIG9yaWVudCk7CiNlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX2Rlc3Ryb3lfc2Nyb2xsYmFyKHNjcm9sbGJhcl9UICpzYikKewogICAgZ3VpX21jaF9zZXRfYmdfY29sb3IoZ3VpLmJhY2tfcGl4ZWwpOwogICAgRGlzcG9zZUNvbnRyb2woc2ItPmlkKTsKI2lmZGVmIERFQlVHX01BQ19TQgogICAgcHJpbnRmKCJkZXN0X3NiICgleCkgXG4iLHNiLT5pZCk7CiNlbmRpZgp9CgoKLyoKICogQ3Vyc29yIGJsaW5rIGZ1bmN0aW9ucy4KICoKICogVGhpcyBpcyBhIHNpbXBsZSBzdGF0ZSBtYWNoaW5lOgogKiBCTElOS19OT05FCW5vdCBibGlua2luZyBhdCBhbGwKICogQkxJTktfT0ZGCWJsaW5raW5nLCBjdXJzb3IgaXMgbm90IHNob3duCiAqIEJMSU5LX09OIGJsaW5raW5nLCBjdXJzb3IgaXMgc2hvd24KICovCiAgICB2b2lkCmd1aV9tY2hfc2V0X2JsaW5raW5nKGxvbmcgd2FpdCwgbG9uZyBvbiwgbG9uZyBvZmYpCnsKICAgIC8qIFRPRE86IFRPRE86IFRPRE86IFRPRE86ICovCi8qICAgIGJsaW5rX3dhaXR0aW1lID0gd2FpdDsKICAgIGJsaW5rX29udGltZSA9IG9uOwogICAgYmxpbmtfb2ZmdGltZSA9IG9mZjsqLwp9CgovKgogKiBTdG9wIHRoZSBjdXJzb3IgYmxpbmtpbmcuICBTaG93IHRoZSBjdXJzb3IgaWYgaXQgd2Fzbid0IHNob3duLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zdG9wX2JsaW5rKHZvaWQpCnsKICAgIGd1aV91cGRhdGVfY3Vyc29yKFRSVUUsIEZBTFNFKTsKICAgIC8qIFRPRE86IFRPRE86IFRPRE86IFRPRE86ICovCi8qICAgIGd1aV93MzJfcm1fYmxpbmtfdGltZXIoKTsKICAgIGlmIChibGlua19zdGF0ZSA9PSBCTElOS19PRkYpCiAgICBndWlfdXBkYXRlX2N1cnNvcihUUlVFLCBGQUxTRSk7CiAgICBibGlua19zdGF0ZSA9IEJMSU5LX05PTkU7Ki8KfQoKLyoKICogU3RhcnQgdGhlIGN1cnNvciBibGlua2luZy4gIElmIGl0IHdhcyBhbHJlYWR5IGJsaW5raW5nLCB0aGlzIHJlc3RhcnRzIHRoZQogKiB3YWl0aW5nIHRpbWUgYW5kIHNob3dzIHRoZSBjdXJzb3IuCiAqLwogICAgdm9pZApndWlfbWNoX3N0YXJ0X2JsaW5rKHZvaWQpCnsKICAgIGd1aV91cGRhdGVfY3Vyc29yKFRSVUUsIEZBTFNFKTsKICAgIC8qIFRPRE86IFRPRE86IFRPRE86IFRPRE86ICovCi8qICAgIGd1aV93MzJfcm1fYmxpbmtfdGltZXIoKTsgKi8KCiAgICAvKiBPbmx5IHN3aXRjaCBibGlua2luZyBvbiBpZiBub25lIG9mIHRoZSB0aW1lcyBpcyB6ZXJvICovCi8qICAgIGlmIChibGlua193YWl0dGltZSAmJiBibGlua19vbnRpbWUgJiYgYmxpbmtfb2ZmdGltZSkKICAgIHsKICAgIGJsaW5rX3RpbWVyID0gU2V0VGltZXIoTlVMTCwgMCwgKFVJTlQpYmxpbmtfd2FpdHRpbWUsCgkJCSAgICAoVElNRVJQUk9DKV9PbkJsaW5rVGltZXIpOwogICAgYmxpbmtfc3RhdGUgPSBCTElOS19PTjsKICAgIGd1aV91cGRhdGVfY3Vyc29yKFRSVUUsIEZBTFNFKTsKICAgIH0qLwp9CgovKgogKiBSZXR1cm4gdGhlIFJHQiB2YWx1ZSBvZiBhIHBpeGVsIGFzIGxvbmcuCiAqLwogICAgbG9uZ191Cmd1aV9tY2hfZ2V0X3JnYihndWljb2xvcl9UIHBpeGVsKQp7CiAgICByZXR1cm4gKFJlZChwaXhlbCkgPDwgMTYpICsgKEdyZWVuKHBpeGVsKSA8PCA4KSArIEJsdWUocGl4ZWwpOwp9CgoKCiNpZmRlZiBGRUFUX0JST1dTRQovKgogKiBQb3Agb3BlbiBhIGZpbGUgYnJvd3NlciBhbmQgcmV0dXJuIHRoZSBmaWxlIHNlbGVjdGVkLCBpbiBhbGxvY2F0ZWQgbWVtb3J5LAogKiBvciBOVUxMIGlmIENhbmNlbCBpcyBoaXQuCiAqICBzYXZpbmcgIC0gVFJVRSBpZiB0aGUgZmlsZSB3aWxsIGJlIHNhdmVkIHRvLCBGQUxTRSBpZiBpdCB3aWxsIGJlIG9wZW5lZC4KICogIHRpdGxlICAgLSBUaXRsZSBtZXNzYWdlIGZvciB0aGUgZmlsZSBicm93c2VyIGRpYWxvZy4KICogIGRmbHQgICAgLSBEZWZhdWx0IG5hbWUgb2YgZmlsZS4KICogIGV4dCAgICAgLSBEZWZhdWx0IGV4dGVuc2lvbiB0byBiZSBhZGRlZCB0byBmaWxlcyB3aXRob3V0IGV4dGVuc2lvbnMuCiAqICBpbml0ZGlyIC0gZGlyZWN0b3J5IGluIHdoaWNoIHRvIG9wZW4gdGhlIGJyb3dzZXIgKE5VTEwgPSBjdXJyZW50IGRpcikKICogIGZpbHRlciAgLSBGaWx0ZXIgZm9yIG1hdGNoZWQgZmlsZXMgdG8gY2hvb3NlIGZyb20uCiAqICBIYXMgYSBmb3JtYXQgbGlrZSB0aGlzOgogKiAgIkMgRmlsZXMgKCouYylcMCouY1wwIgogKiAgIkFsbCBGaWxlc1wwKi4qXDBcMCIKICogIElmIHRoZXNlIHR3byBzdHJpbmdzIHdlcmUgY29uY2F0ZW5hdGVkLCB0aGVuIGEgY2hvaWNlIG9mIHR3byBmaWxlCiAqICBmaWx0ZXJzIHdpbGwgYmUgc2VsZWN0YWJsZSB0byB0aGUgdXNlci4gIFRoZW4gb25seSBtYXRjaGluZyBmaWxlcyB3aWxsCiAqICBiZSBzaG93biBpbiB0aGUgYnJvd3Nlci4gIElmIE5VTEwsIHRoZSBkZWZhdWx0IGFsbG93cyBhbGwgZmlsZXMuCiAqCiAqICAqTk9URSogLSB0aGUgZmlsdGVyIHN0cmluZyBtdXN0IGJlIHRlcm1pbmF0ZWQgd2l0aCBUV08gbnVsbHMuCiAqLwogICAgY2hhcl91ICoKZ3VpX21jaF9icm93c2UoCiAgICBpbnQgc2F2aW5nLAogICAgY2hhcl91ICp0aXRsZSwKICAgIGNoYXJfdSAqZGZsdCwKICAgIGNoYXJfdSAqZXh0LAogICAgY2hhcl91ICppbml0ZGlyLAogICAgY2hhcl91ICpmaWx0ZXIpCnsKICAgIC8qIFRPRE86IEFkZCBBbW1vbidzIHNhZmV0eSBjaGVjbCAoRGFueSkgKi8KICAgIE5hdlJlcGx5UmVjb3JkCXJlcGx5OwogICAgY2hhcl91CQkqZm5hbWUgPSBOVUxMOwogICAgY2hhcl91CQkqKmZuYW1lcyA9IE5VTEw7CiAgICBsb25nCQludW1GaWxlczsKICAgIE5hdkRpYWxvZ09wdGlvbnMJbmF2T3B0aW9uczsKICAgIE9TRXJyCQllcnJvcjsKCiAgICAvKiBHZXQgTmF2aWdhdGlvbiBTZXJ2aWNlIERlZmF1bHRzIHZhbHVlICovCiAgICBOYXZHZXREZWZhdWx0RGlhbG9nT3B0aW9ucygmbmF2T3B0aW9ucyk7CgoKICAgIC8qIFRPRE86IElmIHdlIGdldCBhIDpicm93c2UgYXJncywgc2V0IHRoZSBNdWx0aXBsZSBiaXQuICovCiAgICBuYXZPcHRpb25zLmRpYWxvZ09wdGlvbkZsYWdzID0gIGtOYXZBbGxvd0ludmlzaWJsZUZpbGVzCgkJCQkgfCAga05hdkRvbnRBdXRvVHJhbnNsYXRlCgkJCQkgfCAga05hdkRvbnRBZGRUcmFuc2xhdGVJdGVtcwoJCQkgICAgLyoJIHwgIGtOYXZBbGxvd011bHRpcGxlRmlsZXMgKi8KCQkJCSB8ICBrTmF2QWxsb3dTdGF0aW9uZXJ5OwoKICAgICh2b2lkKSBDMlBhc2NhbFN0cmluZyh0aXRsZSwgICAmbmF2T3B0aW9ucy5tZXNzYWdlKTsKICAgICh2b2lkKSBDMlBhc2NhbFN0cmluZyhkZmx0LCAgICAmbmF2T3B0aW9ucy5zYXZlZEZpbGVOYW1lKTsKICAgIC8qIENvdWxkIHNldCBjbGllbnROYW1lPwogICAgICoJCSB3aW5kb3dUaXRsZT8gKHRoZXJlJ3Mgbm8gdGl0bGUgYmFyPykKICAgICAqLwoKICAgIGlmIChzYXZpbmcpCiAgICB7CgkvKiBDaGFuZ2UgZmlyc3QgcGFybSBBRURlc2MgKHR5cGVGU1MpICpkZWZhdWx0TG9jYXRpb24gdG8gbWF0Y2ggZGZsdCAqLwoJTmF2UHV0RmlsZShOVUxMLCAmcmVwbHksICZuYXZPcHRpb25zLCBOVUxMLCAnVEVYVCcsICdWSU0hJywgTlVMTCk7CglpZiAoIXJlcGx5LnZhbGlkUmVjb3JkKQoJICAgIHJldHVybiBOVUxMOwogICAgfQogICAgZWxzZQogICAgewoJLyogQ2hhbmdlIGZpcnN0IHBhcm0gQUVEZXNjICh0eXBlRlNTKSAqZGVmYXVsdExvY2F0aW9uIHRvIG1hdGNoIGRmbHQgKi8KCU5hdkdldEZpbGUoTlVMTCwgJnJlcGx5LCAmbmF2T3B0aW9ucywgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CglpZiAoIXJlcGx5LnZhbGlkUmVjb3JkKQoJICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGZuYW1lcyA9IG5ld19mbmFtZXNfZnJvbV9BRURlc2MoJnJlcGx5LnNlbGVjdGlvbiwgJm51bUZpbGVzLCAmZXJyb3IpOwoKICAgIE5hdkRpc3Bvc2VSZXBseSgmcmVwbHkpOwoKICAgIGlmIChmbmFtZXMpCiAgICB7CglmbmFtZSA9IGZuYW1lc1swXTsKCXZpbV9mcmVlKGZuYW1lcyk7CiAgICB9CgogICAgLyogVE9ETzogU2hvcnRlbiB0aGUgZmlsZSBuYW1lIGlmIHBvc3NpYmxlICovCiAgICByZXR1cm4gZm5hbWU7Cn0KI2VuZGlmIC8qIEZFQVRfQlJPV1NFICovCgojaWZkZWYgRkVBVF9HVUlfRElBTE9HCi8qCiAqIFN0dWZmIGZvciBkaWFsb2d1ZXMKICovCgovKgogKiBDcmVhdGUgYSBkaWFsb2d1ZSBkeW5hbWljYWxseSBmcm9tIHRoZSBwYXJhbWV0ZXIgc3RyaW5ncy4KICogdHlwZSAgICAgICA9IHR5cGUgb2YgZGlhbG9ndWUgKHF1ZXN0aW9uLCBhbGVydCwgZXRjLikKICogdGl0bGUgICAgICA9IGRpYWxvZ3VlIHRpdGxlLiBtYXkgYmUgTlVMTCBmb3IgZGVmYXVsdCB0aXRsZS4KICogbWVzc2FnZSAgICA9IHRleHQgdG8gZGlzcGxheS4gRGlhbG9ndWUgc2l6ZXMgdG8gYWNjb21tb2RhdGUgaXQuCiAqIGJ1dHRvbnMgICAgPSAnXG4nIHNlcGFyYXRlZCBsaXN0IG9mIGJ1dHRvbiBjYXB0aW9ucywgZGVmYXVsdCBmaXJzdC4KICogZGZsdGJ1dHRvbiA9IG51bWJlciBvZiBkZWZhdWx0IGJ1dHRvbi4KICoKICogVGhpcyByb3V0aW5lIHJldHVybnMgMSBpZiB0aGUgZmlyc3QgYnV0dG9uIGlzIHByZXNzZWQsCiAqCSAgICAyIGZvciB0aGUgc2Vjb25kLCBldGMuCiAqCiAqCSAgICAwIGluZGljYXRlcyBFc2Mgd2FzIHByZXNzZWQuCiAqCSAgICAtMSBmb3IgdW5leHBlY3RlZCBlcnJvcgogKgogKiBJZiBzdHViYmluZyBvdXQgdGhpcyBmbiwgcmV0dXJuIDEuCiAqLwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgc2hvcnQgICBpZHg7CiAgICBzaG9ydCAgIHdpZHRoOwkvKiBTaXplIG9mIHRoZSB0ZXh0IGluIHBpeGVsICovCiAgICBSZWN0ICAgIGJveDsKfSB2Z21EbGdJdG07IC8qIFZpbSBHdWlfTWFjLmMgRGlhbG9nIEl0ZW0gKi8KCiNkZWZpbmUgTW92ZVJlY3RUbyhyLHgseSkgT2Zmc2V0UmVjdChyLHgtci0+bGVmdCx5LXItPnRvcCkKCiAgICBzdGF0aWMgdm9pZAptYWNNb3ZlRGlhbG9nSXRlbSgKICAgIERpYWxvZ1JlZgl0aGVEaWFsb2csCiAgICBzaG9ydAlpdGVtTnVtYmVyLAogICAgc2hvcnQJWCwKICAgIHNob3J0CVksCiAgICBSZWN0CSppbkJveCkKewojaWYgMCAvKiBVU0VfQ0FSQk9OSVpFRCAqLwogICAgLyogVW50ZXN0ZWQgKi8KICAgIE1vdmVEaWFsb2dJdGVtKHRoZURpYWxvZywgaXRlbU51bWJlciwgWCwgWSk7CiAgICBpZiAoaW5Cb3ggIT0gbmlsKQoJR2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGl0ZW1OdW1iZXIsICZpdGVtVHlwZSwgJml0ZW1IYW5kbGUsIGluQm94KTsKI2Vsc2UKICAgIHNob3J0CWl0ZW1UeXBlOwogICAgSGFuZGxlCWl0ZW1IYW5kbGU7CiAgICBSZWN0CWxvY2FsQm94OwogICAgUmVjdAkqaXRlbUJveCA9ICZsb2NhbEJveDsKCiAgICBpZiAoaW5Cb3ggIT0gbmlsKQoJaXRlbUJveCA9IGluQm94OwoKICAgIEdldERpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpdGVtTnVtYmVyLCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCBpdGVtQm94KTsKICAgIE9mZnNldFJlY3QoaXRlbUJveCwgLWl0ZW1Cb3gtPmxlZnQsIC1pdGVtQm94LT50b3ApOwogICAgT2Zmc2V0UmVjdChpdGVtQm94LCBYLCBZKTsKICAgIC8qIFRvIG1vdmUgYSBjb250cm9sIChsaWtlIGEgYnV0dG9uKSB3ZSBuZWVkIHRvIGNhbGwgYm90aAogICAgICogTW92ZUNvbnRyb2wgYW5kIFNldERpYWxvZ0l0ZW0uIEZBUSA2LTE4ICovCiAgICBpZiAoMSkgLyooaXRlbVR5cGUgJiBrQ29udHJvbERpYWxvZ0l0ZW0pICovCglNb3ZlQ29udHJvbCgoQ29udHJvbFJlZikgaXRlbUhhbmRsZSwgWCwgWSk7CiAgICBTZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaXRlbU51bWJlciwgaXRlbVR5cGUsIGl0ZW1IYW5kbGUsIGl0ZW1Cb3gpOwojZW5kaWYKfQoKICAgIHN0YXRpYyB2b2lkCm1hY1NpemVEaWFsb2dJdGVtKAogICAgRGlhbG9nUmVmCXRoZURpYWxvZywKICAgIHNob3J0CWl0ZW1OdW1iZXIsCiAgICBzaG9ydAl3aWR0aCwKICAgIHNob3J0CWhlaWdodCkKewogICAgc2hvcnQJaXRlbVR5cGU7CiAgICBIYW5kbGUJaXRlbUhhbmRsZTsKICAgIFJlY3QJaXRlbUJveDsKCiAgICBHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaXRlbU51bWJlciwgJml0ZW1UeXBlLCAmaXRlbUhhbmRsZSwgJml0ZW1Cb3gpOwoKICAgIC8qIFdoZW4gd2lkdGggb3IgaGVpZ2h0IGlzIHplcm8gZG8gbm90IGNoYW5nZSBpdCAqLwogICAgaWYgKHdpZHRoICA9PSAwKQoJd2lkdGggID0gaXRlbUJveC5yaWdodCAgLSBpdGVtQm94LmxlZnQ7CiAgICBpZiAoaGVpZ2h0ID09IDApCgloZWlnaHQgPSBpdGVtQm94LmJvdHRvbSAtIGl0ZW1Cb3gudG9wOwoKI2lmIDAgLyogVVNFX0NBUkJPTklaRUQgKi8KICAgIFNpemVEaWFsb2dJdGVtKHRoZURpYWxvZywgaXRlbU51bWJlciwgd2lkdGgsIGhlaWdodCk7IC8qIFVudGVzdGVkICovCiNlbHNlCiAgICAvKiBSZXNpemUgdGhlIGJvdW5kaW5nIGJveCAqLwogICAgaXRlbUJveC5yaWdodCAgPSBpdGVtQm94LmxlZnQgKyB3aWR0aDsKICAgIGl0ZW1Cb3guYm90dG9tID0gaXRlbUJveC50b3AgICsgaGVpZ2h0OwoKICAgIC8qIFRvIHJlc2l6ZSBhIGNvbnRyb2wgKGxpa2UgYSBidXR0b24pIHdlIG5lZWQgdG8gY2FsbCBib3RoCiAgICAgKiBTaXplQ29udHJvbCBhbmQgU2V0RGlhbG9nSXRlbS4gKGRlZHVjdGVkIGZyb20gRkFRIDYtMTgpICovCiAgICBpZiAoaXRlbVR5cGUgJiBrQ29udHJvbERpYWxvZ0l0ZW0pCglTaXplQ29udHJvbCgoQ29udHJvbFJlZikgaXRlbUhhbmRsZSwgd2lkdGgsIGhlaWdodCk7CgogICAgLyogQ29uZmlndXJlIGJhY2sgdGhlIGl0ZW0gKi8KICAgIFNldERpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpdGVtTnVtYmVyLCBpdGVtVHlwZSwgaXRlbUhhbmRsZSwgJml0ZW1Cb3gpOwojZW5kaWYKfQoKICAgIHN0YXRpYyB2b2lkCm1hY1NldERpYWxvZ0l0ZW1UZXh0KAogICAgRGlhbG9nUmVmCXRoZURpYWxvZywKICAgIHNob3J0CWl0ZW1OdW1iZXIsCiAgICBTdHIyNTUJaXRlbU5hbWUpCnsKICAgIHNob3J0CWl0ZW1UeXBlOwogICAgSGFuZGxlCWl0ZW1IYW5kbGU7CiAgICBSZWN0CWl0ZW1Cb3g7CgogICAgR2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGl0ZW1OdW1iZXIsICZpdGVtVHlwZSwgJml0ZW1IYW5kbGUsICZpdGVtQm94KTsKCiAgICBpZiAoaXRlbVR5cGUgJiBrQ29udHJvbERpYWxvZ0l0ZW0pCglTZXRDb250cm9sVGl0bGUoKENvbnRyb2xSZWYpIGl0ZW1IYW5kbGUsIGl0ZW1OYW1lKTsKICAgIGVsc2UKCVNldERpYWxvZ0l0ZW1UZXh0KGl0ZW1IYW5kbGUsIGl0ZW1OYW1lKTsKfQoKLyogVE9ETzogVGhlcmUgaGF2ZSBiZWVuIHNvbWUgY3Jhc2hlcyB3aXRoIGRpYWxvZ3MsIGNoZWNrIHlvdXIgaW5ib3gKICogKEp1c3NpKQogKi8KICAgIGludApndWlfbWNoX2RpYWxvZygKICAgIGludAkJdHlwZSwKICAgIGNoYXJfdQkqdGl0bGUsCiAgICBjaGFyX3UJKm1lc3NhZ2UsCiAgICBjaGFyX3UJKmJ1dHRvbnMsCiAgICBpbnQJCWRmbHRidXR0b24sCiAgICBjaGFyX3UJKnRleHRmaWVsZCkKewogICAgSGFuZGxlCWJ1dHRvbkRJVEw7CiAgICBIYW5kbGUJaWNvbkRJVEw7CiAgICBIYW5kbGUJaW5wdXRESVRMOwogICAgSGFuZGxlCW1lc3NhZ2VESVRMOwogICAgSGFuZGxlCWl0ZW1IYW5kbGU7CiAgICBIYW5kbGUJaWNvbkhhbmRsZTsKICAgIERpYWxvZ1B0cgl0aGVEaWFsb2c7CiAgICBjaGFyX3UJbGVuOwogICAgY2hhcl91CVBhc2NhbFRpdGxlWzI1Nl07CS8qIHBsYWNlIGhvbGRlciBmb3IgdGhlIHRpdGxlICovCiAgICBjaGFyX3UJbmFtZVsyNTZdOwogICAgR3JhZlB0cglvbGRQb3J0OwogICAgc2hvcnQJaXRlbUhpdDsKICAgIGNoYXJfdQkqYnV0dG9uQ2hhcjsKICAgIFJlY3QJYm94OwogICAgc2hvcnQJYnV0dG9uOwogICAgc2hvcnQJbGFzdEJ1dHRvbjsKICAgIHNob3J0CWl0ZW1UeXBlOwogICAgc2hvcnQJdXNlSWNvbjsKICAgIHNob3J0CXdpZHRoOwogICAgc2hvcnQJdG90YWxCdXR0b25XaWR0aCA9IDA7ICAgLyogdGhlIHdpZHRoIG9mIGFsbCBidXR0b24gdG9nZXRoZXIgaW5jdWRpbmcgc3BhY2luZyAqLwogICAgc2hvcnQJd2lkZXN0QnV0dG9uID0gMDsKICAgIHNob3J0CWRmbHRCdXR0b25FZGdlICAgICA9IDIwOyAgLyogZ3V0IGZlZWxpbmcgKi8KICAgIHNob3J0CWRmbHRFbGVtZW50U3BhY2luZyA9IDEzOyAgLyogZnJvbSBJTTpWLjItMjkgKi8KICAgIHNob3J0ICAgICAgIGRmbHRJY29uU2lkZVNwYWNlICA9IDIzOyAgLyogZnJvbSBJTTpWLjItMjkgKi8KICAgIHNob3J0CW1heGltdW1XaWR0aCAgICAgICA9IDQwMDsgLyogZ3V0IGZlZWxpbmcgKi8KICAgIHNob3J0CW1heEJ1dHRvbldpZHRoCSAgID0gMTc1OyAvKiBndXQgZmVlbGluZyAqLwoKICAgIHNob3J0CXZlcnRpY2FsOwogICAgc2hvcnQJZGlhbG9nSGVpZ2h0OwogICAgc2hvcnQJbWVzc2FnZUxpbmVzID0gMzsKICAgIEZvbnRJbmZvCXRleHRGb250SW5mbzsKCiAgICB2Z21EbGdJdG0gICBpY29uSXRtOwogICAgdmdtRGxnSXRtICAgbWVzc2FnZUl0bTsKICAgIHZnbURsZ0l0bSAgIGlucHV0SXRtOwogICAgdmdtRGxnSXRtICAgYnV0dG9uSXRtOwoKICAgIFdpbmRvd1JlZgl0aGVXaW5kb3c7CgogICAgLyogQ2hlY2sgJ3YnIGZsYWcgaW4gJ2d1aW9wdGlvbnMnOiB2ZXJ0aWNhbCBidXR0b24gcGxhY2VtZW50LiAqLwogICAgdmVydGljYWwgPSAodmltX3N0cmNocihwX2dvLCBHT19WRVJUSUNBTCkgIT0gTlVMTCk7CgogICAgLyogQ3JlYXRlIGEgbmV3IERpYWxvZyBCb3ggZnJvbSB0ZW1wbGF0ZS4gKi8KICAgIHRoZURpYWxvZyA9IEdldE5ld0RpYWxvZygxMjksIG5pbCwgKFdpbmRvd1JlZikgLTEpOwoKICAgIC8qIEdldCB0aGUgV2luZG93UmVmICovCiAgICB0aGVXaW5kb3cgPSBHZXREaWFsb2dXaW5kb3codGhlRGlhbG9nKTsKCiAgICAvKiBIaWRlIHRoZSB3aW5kb3cuCiAgICAgKiAxLiB0byBhdm9pZCBzZWVpbmcgc2xvdyBkcmF3aW5nCiAgICAgKiAyLiB0byBwcmV2ZW50IGEgcHJvYmxlbSBzZWVuIHdoaWxlIG1vdmluZyBkaWFsb2cgaXRlbQogICAgICogICAgd2l0aGluIGEgdmlzaWJsZSB3aW5kb3cuIChub24tQ2FyYm9uIE1hY09TIDkpCiAgICAgKiBDb3VsZCBiZSBhdm9pZGVkIGJ5IGNoYW5naW5nIHRoZSByZXNvdXJjZS4KICAgICAqLwogICAgSGlkZVdpbmRvdyh0aGVXaW5kb3cpOwoKICAgIC8qIENoYW5nZSB0aGUgZ3JhcGhpY2FsIHBvcnQgdG8gdGhlIGRpYWxvZywKICAgICAqIHNvIHdlIGNhbiBtZWFzdXJlIHRoZSB0ZXh0IHdpdGggdGhlIHByb3BlciBmb250ICovCiAgICBHZXRQb3J0KCZvbGRQb3J0KTsKICAgIFNldFBvcnREaWFsb2dQb3J0KHRoZURpYWxvZyk7CgogICAgLyogR2V0IHRoZSBpbmZvIGFib3V0IHRoZSBkZWZhdWx0IHRleHQsCiAgICAgKiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgaGVpZ2h0IG9mIHRoZSBtZXNzYWdlCiAgICAgKiBhbmQgb2YgdGhlICB0ZXh0IGZpZWxkICovCiAgICBHZXRGb250SW5mbygmdGV4dEZvbnRJbmZvKTsKCiAgICAvKglTZXQgdGhlIGRpYWxvZyB0aXRsZSAqLwogICAgaWYgKHRpdGxlICE9IE5VTEwpCiAgICB7Cgkodm9pZCkgQzJQYXNjYWxTdHJpbmcodGl0bGUsICZQYXNjYWxUaXRsZSk7CglTZXRXVGl0bGUodGhlV2luZG93LCBQYXNjYWxUaXRsZSk7CiAgICB9CgogICAgLyogQ3JlYXRlcyB0aGUgYnV0dG9ucyBhbmQgYWRkIHRoZW0gdG8gdGhlIERpYWxvZyBCb3guICovCiAgICBidXR0b25ESVRMID0gR2V0UmVzb3VyY2UoJ0RJVEwnLCAxMzApOwogICAgYnV0dG9uQ2hhciA9IGJ1dHRvbnM7CiAgICBidXR0b24gPSAwOwoKICAgIGZvciAoOypidXR0b25DaGFyICE9IDA7KQogICAgewoJLyogR2V0IHRoZSBuYW1lIG9mIHRoZSBidXR0b24gKi8KCWJ1dHRvbisrOwoJbGVuID0gMDsKCWZvciAoOygoKmJ1dHRvbkNoYXIgIT0gRExHX0JVVFRPTl9TRVApICYmICgqYnV0dG9uQ2hhciAhPSAwKSAmJiAobGVuIDwgMjU1KSk7IGJ1dHRvbkNoYXIrKykKCXsKCSAgICBpZiAoKmJ1dHRvbkNoYXIgIT0gRExHX0hPVEtFWV9DSEFSKQoJCW5hbWVbKytsZW5dID0gKmJ1dHRvbkNoYXI7Cgl9CglpZiAoKmJ1dHRvbkNoYXIgIT0gMCkKCSAgYnV0dG9uQ2hhcisrOwoJbmFtZVswXSA9IGxlbjsKCgkvKiBBZGQgdGhlIGJ1dHRvbiAqLwoJQXBwZW5kRElUTCh0aGVEaWFsb2csIGJ1dHRvbkRJVEwsIG92ZXJsYXlESVRMKTsgLyogYXBwZW5kRElUTFJpZ2h0KTsgKi8KCgkvKiBDaGFuZ2UgdGhlIGJ1dHRvbidzIG5hbWUgKi8KCW1hY1NldERpYWxvZ0l0ZW1UZXh0KHRoZURpYWxvZywgYnV0dG9uLCBuYW1lKTsKCgkvKiBSZXNpemUgdGhlIGJ1dHRvbiB0byBmaXQgaXRzIG5hbWUgKi8KCXdpZHRoID0gU3RyaW5nV2lkdGgobmFtZSkgKyAyICogZGZsdEJ1dHRvbkVkZ2U7CgkvKiBMaW1pdGUgdGhlIHNpemUgb2YgYW55IGJ1dHRvbiB0byBhbiBhY2NlcHRhYmxlIHZhbHVlLiAqLwoJLyogVE9ETzogU2hvdWxkIGJlIGJhc2VkIG9uIHRoZSBtZXNzYWdlIHdpZHRoICovCglpZiAod2lkdGggPiBtYXhCdXR0b25XaWR0aCkKCSAgICB3aWR0aCA9IG1heEJ1dHRvbldpZHRoOwoJbWFjU2l6ZURpYWxvZ0l0ZW0odGhlRGlhbG9nLCBidXR0b24sIHdpZHRoLCAwKTsKCgl0b3RhbEJ1dHRvbldpZHRoICs9IHdpZHRoOwoKCWlmICh3aWR0aCA+IHdpZGVzdEJ1dHRvbikKCSAgICB3aWRlc3RCdXR0b24gPSB3aWR0aDsKICAgIH0KICAgIFJlbGVhc2VSZXNvdXJjZShidXR0b25ESVRMKTsKICAgIGxhc3RCdXR0b24gPSBidXR0b247CgogICAgLyogQWRkIHRoZSBpY29uIHRvIHRoZSBEaWFsb2cgQm94LiAqLwogICAgaWNvbkl0bS5pZHggPSBsYXN0QnV0dG9uICsgMTsKICAgIGljb25ESVRMID0gR2V0UmVzb3VyY2UoJ0RJVEwnLCAxMzEpOwogICAgc3dpdGNoICh0eXBlKQogICAgewoJY2FzZSBWSU1fR0VORVJJQzogIHVzZUljb24gPSBrTm90ZUljb247CgljYXNlIFZJTV9FUlJPUjogICAgdXNlSWNvbiA9IGtTdG9wSWNvbjsKCWNhc2UgVklNX1dBUk5JTkc6ICB1c2VJY29uID0ga0NhdXRpb25JY29uOwoJY2FzZSBWSU1fSU5GTzogICAgIHVzZUljb24gPSBrTm90ZUljb247CgljYXNlIFZJTV9RVUVTVElPTjogdXNlSWNvbiA9IGtOb3RlSWNvbjsKCWRlZmF1bHQ6ICAgICAgdXNlSWNvbiA9IGtTdG9wSWNvbjsKICAgIH07CiAgICBBcHBlbmRESVRMKHRoZURpYWxvZywgaWNvbkRJVEwsIG92ZXJsYXlESVRMKTsKICAgIFJlbGVhc2VSZXNvdXJjZShpY29uRElUTCk7CiAgICBHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaWNvbkl0bS5pZHgsICZpdGVtVHlwZSwgJml0ZW1IYW5kbGUsICZib3gpOwogICAgLyogVE9ETzogU2hvdWxkIHRoZSBpdGVtIGJlIGZyZWVkPyAqLwogICAgaWNvbkhhbmRsZSA9IEdldEljb24odXNlSWNvbik7CiAgICBTZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaWNvbkl0bS5pZHgsIGl0ZW1UeXBlLCBpY29uSGFuZGxlLCAmYm94KTsKCiAgICAvKiBBZGQgdGhlIG1lc3NhZ2UgdG8gdGhlIERpYWxvZyBib3guICovCiAgICBtZXNzYWdlSXRtLmlkeCA9IGxhc3RCdXR0b24gKyAyOwogICAgbWVzc2FnZURJVEwgPSBHZXRSZXNvdXJjZSgnRElUTCcsIDEzMik7CiAgICBBcHBlbmRESVRMKHRoZURpYWxvZywgbWVzc2FnZURJVEwsIG92ZXJsYXlESVRMKTsKICAgIFJlbGVhc2VSZXNvdXJjZShtZXNzYWdlRElUTCk7CiAgICBHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgbWVzc2FnZUl0bS5pZHgsICZpdGVtVHlwZSwgJml0ZW1IYW5kbGUsICZib3gpOwogICAgKHZvaWQpIEMyUGFzY2FsU3RyaW5nKG1lc3NhZ2UsICZuYW1lKTsKICAgIFNldERpYWxvZ0l0ZW1UZXh0KGl0ZW1IYW5kbGUsIG5hbWUpOwogICAgbWVzc2FnZUl0bS53aWR0aCA9IFN0cmluZ1dpZHRoKG5hbWUpOwoKICAgIC8qIEFkZCB0aGUgaW5wdXQgYm94IGlmIG5lZWRlZCAqLwogICAgaWYgKHRleHRmaWVsZCAhPSBOVUxMKQogICAgewoJLyogQ2hlYXQgZm9yIG5vdyByZXVzZSB0aGUgbWVzc2FnZSBhbmQgY29udmVydCB0byB0ZXh0IGVkaXQgKi8KCWlucHV0SXRtLmlkeCA9IGxhc3RCdXR0b24gKyAzOwoJaW5wdXRESVRMID0gR2V0UmVzb3VyY2UoJ0RJVEwnLCAxMzIpOwoJQXBwZW5kRElUTCh0aGVEaWFsb2csIGlucHV0RElUTCwgb3ZlcmxheURJVEwpOwoJUmVsZWFzZVJlc291cmNlKGlucHV0RElUTCk7CglHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaW5wdXRJdG0uaWR4LCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCAmYm94KTsKLyoJICBTZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaW5wdXRJdG0uaWR4LCBrRWRpdFRleHREaWFsb2dJdGVtLCBpdGVtSGFuZGxlLCAmYm94KTsqLwoJKHZvaWQpIEMyUGFzY2FsU3RyaW5nKHRleHRmaWVsZCwgJm5hbWUpOwoJU2V0RGlhbG9nSXRlbVRleHQoaXRlbUhhbmRsZSwgbmFtZSk7CglpbnB1dEl0bS53aWR0aCA9IFN0cmluZ1dpZHRoKG5hbWUpOwogICAgfQoKICAgIC8qIFNldCB0aGUgPEVOVEVSPiBhbmQgPEVTQz4gYnV0dG9uLiAqLwogICAgU2V0RGlhbG9nRGVmYXVsdEl0ZW0odGhlRGlhbG9nLCBkZmx0YnV0dG9uKTsKICAgIFNldERpYWxvZ0NhbmNlbEl0ZW0odGhlRGlhbG9nLCAwKTsKCiAgICAvKiBSZXBvc2l0aW9uIGVsZW1lbnQgKi8KCiAgICAvKiBDaGVjayBpZiB3ZSBuZWVkIHRvIGZvcmNlIHZlcnRpY2FsICovCiAgICBpZiAodG90YWxCdXR0b25XaWR0aCA+IG1heGltdW1XaWR0aCkKCXZlcnRpY2FsID0gVFJVRTsKCiAgICAvKiBQbGFjZSBpY29uICovCiAgICBtYWNNb3ZlRGlhbG9nSXRlbSh0aGVEaWFsb2csIGljb25JdG0uaWR4LCBkZmx0SWNvblNpZGVTcGFjZSwgZGZsdEVsZW1lbnRTcGFjaW5nLCAmYm94KTsKICAgIGljb25JdG0uYm94LnJpZ2h0ID0gYm94LnJpZ2h0OwogICAgaWNvbkl0bS5ib3guYm90dG9tID0gYm94LmJvdHRvbTsKCiAgICAvKiBQbGFjZSBNZXNzYWdlICovCiAgICBtZXNzYWdlSXRtLmJveC5sZWZ0ID0gaWNvbkl0bS5ib3gucmlnaHQgKyBkZmx0SWNvblNpZGVTcGFjZTsKICAgIG1hY1NpemVEaWFsb2dJdGVtKHRoZURpYWxvZywgbWVzc2FnZUl0bS5pZHgsIDAsICBtZXNzYWdlTGluZXMgKiAodGV4dEZvbnRJbmZvLmFzY2VudCArIHRleHRGb250SW5mby5kZXNjZW50KSk7CiAgICBtYWNNb3ZlRGlhbG9nSXRlbSh0aGVEaWFsb2csIG1lc3NhZ2VJdG0uaWR4LCBtZXNzYWdlSXRtLmJveC5sZWZ0LCBkZmx0RWxlbWVudFNwYWNpbmcsICZtZXNzYWdlSXRtLmJveCk7CgogICAgLyogUGxhY2UgSW5wdXQgKi8KICAgIGlmICh0ZXh0ZmllbGQgIT0gTlVMTCkKICAgIHsKCWlucHV0SXRtLmJveC5sZWZ0ID0gbWVzc2FnZUl0bS5ib3gubGVmdDsKCWlucHV0SXRtLmJveC50b3AgID0gbWVzc2FnZUl0bS5ib3guYm90dG9tICsgZGZsdEVsZW1lbnRTcGFjaW5nOwoJbWFjU2l6ZURpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpbnB1dEl0bS5pZHgsIDAsIHRleHRGb250SW5mby5hc2NlbnQgKyB0ZXh0Rm9udEluZm8uZGVzY2VudCk7CgltYWNNb3ZlRGlhbG9nSXRlbSh0aGVEaWFsb2csIGlucHV0SXRtLmlkeCwgaW5wdXRJdG0uYm94LmxlZnQsIGlucHV0SXRtLmJveC50b3AsICZpbnB1dEl0bS5ib3gpOwoJLyogQ29udmVydCB0aGUgc3RhdGljIHRleHQgaW50byBhIHRleHQgZWRpdC4KCSAqIEZvciBzb21lIHJlYXNvbiB0aGlzIGNoYW5nZSBuZWVkIHRvIGJlIGRvbmUgbGFzdCAoRGFueSkgKi8KCUdldERpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpbnB1dEl0bS5pZHgsICZpdGVtVHlwZSwgJml0ZW1IYW5kbGUsICZpbnB1dEl0bS5ib3gpOwoJU2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGlucHV0SXRtLmlkeCwga0VkaXRUZXh0RGlhbG9nSXRlbSwgaXRlbUhhbmRsZSwgJmlucHV0SXRtLmJveCk7CglTZWxlY3REaWFsb2dJdGVtVGV4dCh0aGVEaWFsb2csIGlucHV0SXRtLmlkeCwgMCwgMzI3NjcpOwogICAgfQoKICAgIC8qIFBsYWNlIEJ1dHRvbiAqLwogICAgaWYgKHRleHRmaWVsZCAhPSBOVUxMKQogICAgewoJYnV0dG9uSXRtLmJveC5sZWZ0ID0gaW5wdXRJdG0uYm94LmxlZnQ7CglidXR0b25JdG0uYm94LnRvcCAgPSBpbnB1dEl0bS5ib3guYm90dG9tICsgZGZsdEVsZW1lbnRTcGFjaW5nOwogICAgfQogICAgZWxzZQogICAgewoJYnV0dG9uSXRtLmJveC5sZWZ0ID0gbWVzc2FnZUl0bS5ib3gubGVmdDsKCWJ1dHRvbkl0bS5ib3gudG9wICA9IG1lc3NhZ2VJdG0uYm94LmJvdHRvbSArIGRmbHRFbGVtZW50U3BhY2luZzsKICAgIH0KCiAgICBmb3IgKGJ1dHRvbj0xOyBidXR0b24gPD0gbGFzdEJ1dHRvbjsgYnV0dG9uKyspCiAgICB7CgoJbWFjTW92ZURpYWxvZ0l0ZW0odGhlRGlhbG9nLCBidXR0b24sIGJ1dHRvbkl0bS5ib3gubGVmdCwgYnV0dG9uSXRtLmJveC50b3AsICZib3gpOwoJLyogV2l0aCB2ZXJ0aWNhbCwgaXQncyBiZXR0ZXIgdG8gaGF2ZSBhbGwgYnV0dG9uIHRoZSBzYW1lIGxlbmdodCAqLwoJaWYgKHZlcnRpY2FsKQoJewoJICAgIG1hY1NpemVEaWFsb2dJdGVtKHRoZURpYWxvZywgYnV0dG9uLCB3aWRlc3RCdXR0b24sIDApOwoJICAgIEdldERpYWxvZ0l0ZW0odGhlRGlhbG9nLCBidXR0b24sICZpdGVtVHlwZSwgJml0ZW1IYW5kbGUsICZib3gpOwoJfQoJLyogQ2FsY3VsYXRlIHBvc2l0aW9uIG9mIG5leHQgYnV0dG9uICovCglpZiAodmVydGljYWwpCgkgICAgYnV0dG9uSXRtLmJveC50b3AgID0gYm94LmJvdHRvbSArIGRmbHRFbGVtZW50U3BhY2luZzsKCWVsc2UKCSAgICBidXR0b25JdG0uYm94LmxlZnQgID0gYm94LnJpZ2h0ICsgZGZsdEVsZW1lbnRTcGFjaW5nOwogICAgfQoKICAgIC8qIFJlc2l6ZSB0aGUgZGlhbG9nIGJveCAqLwogICAgZGlhbG9nSGVpZ2h0ID0gYm94LmJvdHRvbSArIGRmbHRFbGVtZW50U3BhY2luZzsKICAgIFNpemVXaW5kb3codGhlV2luZG93LCBtYXhpbXVtV2lkdGgsIGRpYWxvZ0hlaWdodCwgVFJVRSk7CgogICAgLyogTWFnaWMgcmVzaXplICovCiAgICBBdXRvU2l6ZURpYWxvZyh0aGVEaWFsb2cpOwogICAgLyogTmVlZCBhIGhvcml6b250YWwgcmVzaXplIGFueXdheSBzbyBub3QgdGhhdCB1c2VmdWwgKi8KCiAgICAvKiBEaXNwbGF5IGl0ICovCiAgICBTaG93V2luZG93KHRoZVdpbmRvdyk7Ci8qICBCcmluZ1RvRnJvbnQodGhlV2luZG93KTsgKi8KICAgIFNlbGVjdFdpbmRvdyh0aGVXaW5kb3cpOwoKLyogIERyYXdEaWFsb2codGhlRGlhbG9nKTsgKi8KI2lmIDAKICAgIEdldFBvcnQoJm9sZFBvcnQpOwogICAgU2V0UG9ydERpYWxvZ1BvcnQodGhlRGlhbG9nKTsKI2VuZGlmCgojaWZkZWYgVVNFX0NBUkJPTktFWUhBTkRMRVIKICAgIC8qIEF2b2lkIHRoYXQgd2UgdXNlIGtleSBldmVudHMgZm9yIHRoZSBtYWluIHdpbmRvdy4gKi8KICAgIGRpYWxvZ19idXN5ID0gVFJVRTsKI2VuZGlmCgogICAgLyogSGFuZyB1bnRpbCBvbmUgb2YgdGhlIGJ1dHRvbiBpcyBoaXQgKi8KICAgIGRvCiAgICB7CglNb2RhbERpYWxvZyhuaWwsICZpdGVtSGl0KTsKICAgIH0gd2hpbGUgKChpdGVtSGl0IDwgMSkgfHwgKGl0ZW1IaXQgPiBsYXN0QnV0dG9uKSk7CgojaWZkZWYgVVNFX0NBUkJPTktFWUhBTkRMRVIKICAgIGRpYWxvZ19idXN5ID0gRkFMU0U7CiNlbmRpZgoKICAgIC8qIENvcHkgYmFjayB0aGUgdGV4dCBlbnRlcmVkIGJ5IHRoZSB1c2VyIGludG8gdGhlIHBhcmFtICovCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCiAgICB7CglHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaW5wdXRJdG0uaWR4LCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCAmYm94KTsKCUdldERpYWxvZ0l0ZW1UZXh0KGl0ZW1IYW5kbGUsIChjaGFyX3UgKikgJm5hbWUpOwojaWYgSU9TSVpFIDwgMjU2CgkvKiBUcnVuY2F0ZSB0aGUgbmFtZSB0byBJT1NJWkUgaWYgbmVlZGVkICovCglpZiAobmFtZVswXSA+IElPU0laRSkKCSAgICBuYW1lWzBdID0gSU9TSVpFIC0gMTsKI2VuZGlmCgl2aW1fc3RybmNweSh0ZXh0ZmllbGQsICZuYW1lWzFdLCBuYW1lWzBdKTsKICAgIH0KCiAgICAvKiBSZXN0b3JlIHRoZSBvcmlnaW5hbCBncmFwaGljYWwgcG9ydCAqLwogICAgU2V0UG9ydChvbGRQb3J0KTsKCiAgICAvKiBHZXQgcmlkZSBvZiB0aCBlZGlhbG9nIChmcmVlIG1lbW9yeSkgKi8KICAgIERpc3Bvc2VEaWFsb2codGhlRGlhbG9nKTsKCiAgICByZXR1cm4gaXRlbUhpdDsKLyoKICogVXNlZnVsbCB0aGluZyB3aGljaCBjb3VsZCBiZSB1c2VkCiAqIFNldERpYWxvZ1RpbWVvdXQoKTogQXV0byBjbGljayBhIGJ1dHRvbiBhZnRlciB0aW1lb3V0CiAqIFNldERpYWxvZ1RyYWNrc0N1cnNvcigpIDogR2V0IHRoZSBJLWJlYW0gY3Vyc29yIG92ZXIgaW5wdXQgYm94CiAqIE1vdmVEaWFsb2dJdGVtKCk6CSAgICBQcm9iYWJseSBiZXR0ZXIgdGhhbiBTZXREaWFsb2dJdGVtCiAqIFNpemVEaWFsb2dJdGVtKCk6CQkoYnV0IGlzIGl0IENhcmJvbiBPbmx5PykKICogQXV0b1NpemVEaWFsb2coKToJICAgIE1hZ2ljIHJlc2l6ZSBvZiBkaWFsb2cgYmFzZWQgb24gdGV4dCBsZW5naHQKICovCn0KI2VuZGlmIC8qIEZFQVRfRElBTE9HX0dVSSAqLwoKLyoKICogRGlzcGxheSB0aGUgc2F2ZWQgZXJyb3IgbWVzc2FnZShzKS4KICovCiNpZmRlZiBVU0VfTUNIX0VSUk1TRwogICAgdm9pZApkaXNwbGF5X2Vycm9ycyh2b2lkKQp7CiAgICBjaGFyCSpwOwogICAgY2hhcl91CXBFcnJvclsyNTZdOwoKICAgIGlmIChlcnJvcl9nYS5nYV9kYXRhID09IE5VTEwpCglyZXR1cm47CgogICAgLyogYXZvaWQgcHV0dGluZyB1cCBhIG1lc3NhZ2UgYm94IHdpdGggYmxhbmtzIG9ubHkgKi8KICAgIGZvciAocCA9IChjaGFyICopZXJyb3JfZ2EuZ2FfZGF0YTsgKnA7ICsrcCkKCWlmICghaXNzcGFjZSgqcCkpCgl7CgkgICAgaWYgKFNUUkxFTihwKSA+IDI1NSkKCQlwRXJyb3JbMF0gPSAyNTU7CgkgICAgZWxzZQoJCXBFcnJvclswXSA9IFNUUkxFTihwKTsKCgkgICAgU1RSTkNQWSgmcEVycm9yWzFdLCBwLCBwRXJyb3JbMF0pOwoJICAgIFBhcmFtVGV4dChwRXJyb3IsIG5pbCwgbmlsLCBuaWwpOwoJICAgIEFsZXJ0KDEyOCwgbmlsKTsKCSAgICBicmVhazsKCSAgICAvKiBUT0RPOiBoYW5kbGVkIG1lc3NhZ2UgbG9uZ2VyIHRoYW4gMjU2IGNoYXJzCgkgICAgICoJIHVzZSBhdXRvLXNpemVhYmxlIGFsZXJ0CgkgICAgICoJIG9yIGRpYWxvZyB3aXRoIHNjcm9sbGJhcnMgKFRleHRFZGl0IHpvbmUpCgkgICAgICovCgl9CiAgICBnYV9jbGVhcigmZXJyb3JfZ2EpOwp9CiNlbmRpZgoKLyoKICogR2V0IGN1cnJlbnQgbW91c2UgY29vcmRpbmF0ZXMgaW4gdGV4dCB3aW5kb3cuCiAqLwogICAgdm9pZApndWlfbWNoX2dldG1vdXNlKGludCAqeCwgaW50ICp5KQp7CiAgICBQb2ludCB3aGVyZTsKCiAgICBHZXRNb3VzZSgmd2hlcmUpOwoKICAgICp4ID0gd2hlcmUuaDsKICAgICp5ID0gd2hlcmUudjsKfQoKICAgIHZvaWQKZ3VpX21jaF9zZXRtb3VzZShpbnQgeCwgaW50IHkpCnsKICAgIC8qIFRPRE8gKi8KI2lmIDAKICAgIC8qIEZyb20gRkFRIDMtMTEgKi8KCiAgICBDdXJzb3JEZXZpY2VQdHIgbXlNb3VzZTsKICAgIFBvaW50CSAgICB3aGVyZTsKCiAgICBpZiAoICAgTkdldFRyYXBBZGRyZXNzKF9DdXJzb3JEZXZpY2VEaXNwYXRjaCwgVG9vbFRyYXApCgkhPSBOR2V0VHJhcEFkZHJlc3MoX1VuaW1wbGVtZW50ZWQsICAgVG9vbFRyYXApKQogICAgewoJLyogTmV3IHdheSAqLwoKCS8qCgkgKiBHZXQgZmlyc3QgZGV2b2ljZSB3aXRoIG9uZSBidXR0b24uCgkgKiBUaGlzIHdpbGwgcHJvYmFibHkgYmUgdGhlIHN0YW5kYWQgbW91c2UKCSAqIHN0YXJ0YXQgaGVhZCBvZiBjdXJzb3IgZGV2IGxpc3QKCSAqCgkgKi8KCglteU1vdXNlID0gbmlsOwoKCWRvCgl7CgkgICAgLyogR2V0IHRoZSBuZXh0IGN1cnNvciBkZXZpY2UgKi8KCSAgICBDdXJzb3JEZXZpY2VOZXh0RGV2aWNlKCZteU1vdXNlKTsKCX0KCXdoaWxlICgobXlNb3VzZSAhPSBuaWwpICYmIChteU1vdXNlLT5jbnRCdXR0b25zICE9IDEpKTsKCglDdXJzb3JEZXZpY2VNb3ZlVG8obXlNb3VzZSwgeCwgeSk7CiAgICB9CiAgICBlbHNlCiAgICB7CgkvKiBPbGQgd2F5ICovCgl3aGVyZS5oID0geDsKCXdoZXJlLnYgPSB5OwoKCSooUG9pbnQgKilSYXdNb3VzZSA9IHdoZXJlOwoJKihQb2ludCAqKU1UZW1wICAgID0gd2hlcmU7CgkqKFB0cikgICAgQ3Jzck5ldyAgPSAweEZGRkY7CiAgICB9CiNlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX3Nob3dfcG9wdXBtZW51KHZpbW1lbnVfVCAqbWVudSkKewovKgogKiAgQ2xvbmUgUG9wVXAgdG8gdXNlIG1lbnUKICogIENyZWF0ZSBhIG9iamVjdCBkZXNjcmlwdG9yIGZvciB0aGUgY3VycmVudCBzZWxlY3Rpb24KICogIENhbGwgdGhlIHByb2NlZHVyZQogKi8KCiAgICBNZW51SGFuZGxlCUNudHhNZW51OwogICAgUG9pbnQJd2hlcmU7CiAgICBPU1N0YXR1cwlzdGF0dXM7CiAgICBVSW50MzIJQ250eFR5cGU7CiAgICBTSW50MTYJQ250eE1lbnVJRDsKICAgIFVJbnQxNglDbnR4TWVudUl0ZW07CiAgICBTdHIyNTUJSGVscE5hbWUgPSAiIjsKICAgIEdyYWZQdHIJc2F2ZVBvcnQ7CgogICAgLyogU2F2ZSBDdXJyZW50IFBvcnQ6IE9uIE1hY09TIFggd2Ugc2VlbSB0byBsb3NlIHRoZSBwb3J0ICovCiAgICBHZXRQb3J0KCZzYXZlUG9ydCk7IC8qT1NYKi8KCiAgICBHZXRNb3VzZSgmd2hlcmUpOwogICAgTG9jYWxUb0dsb2JhbCgmd2hlcmUpOyAvKk9TWCovCiAgICBDbnR4TWVudSA9IG1lbnUtPnN1Ym1lbnVfaGFuZGxlOwoKICAgIC8qIFRPRE86IEdldCB0aGUgdGV4dCBzZWxlY3Rpb24gZnJvbSBWaW0gKi8KCiAgICAvKiBDYWxsIHRvIEhhbmRsZSBQb3B1cCAqLwogICAgc3RhdHVzID0gQ29udGV4dHVhbE1lbnVTZWxlY3QoQ250eE1lbnUsIHdoZXJlLCBmYWxzZSwga0NNSGVscEl0ZW1Ob0hlbHAsIEhlbHBOYW1lLCBOVUxMLCAmQ250eFR5cGUsICZDbnR4TWVudUlELCAmQ250eE1lbnVJdGVtKTsKCiAgICBpZiAoc3RhdHVzID09IG5vRXJyKQogICAgewoJaWYgKENudHhUeXBlID09IGtDTU1lbnVJdGVtU2VsZWN0ZWQpCgl7CgkgICAgLyogSGFuZGxlIHRoZSBtZW51IENudHhNZW51SUQsIENudHhNZW51SXRlbSAqLwoJICAgIC8qIFRoZSBzdWJtZW51IGNhbiBiZSBoYW5kbGUgZGlyZWN0bHkgYnkgZ3VpX21hY19oYW5kbGVfbWVudSAqLwoJICAgIC8qIEJ1dCB3aGF0IGFib3V0IHRoZSBjdXJyZW50IG1lbnUsIGlzIHRoZSBtZW51IGNoYW5nZWQgYnkgQ29udGV4dHVhbE1lbnVTZWxlY3QgKi8KCSAgICBndWlfbWFjX2hhbmRsZV9tZW51KChDbnR4TWVudUlEIDw8IDE2KSArIENudHhNZW51SXRlbSk7Cgl9CgllbHNlIGlmIChDbnR4TWVudUlEID09IGtDTVNob3dIZWxwU2VsZWN0ZWQpCgl7CgkgICAgLyogU2hvdWxkIGNvbWUgdXAgd2l0aCB0aGUgaGVscCAqLwoJfQogICAgfQoKICAgIC8qIFJlc3RvcmUgb3JpZ2luYWwgUG9ydCAqLwogICAgU2V0UG9ydChzYXZlUG9ydCk7IC8qT1NYKi8KfQoKI2lmIGRlZmluZWQoRkVBVF9DV19FRElUT1IpIHx8IGRlZmluZWQoUFJPVE8pCi8qIFRPRE86IElzIGl0IG5lZWQgZm9yIE1BQ09TX1g/IChEYW55KSAqLwogICAgdm9pZAptY2hfcG9zdF9idWZmZXJfd3JpdGUoYnVmX1QgKmJ1ZikKewogICAgR2V0RlNTcGVjRnJvbVBhdGgoYnVmLT5iX2ZmbmFtZSwgJmJ1Zi0+Yl9GU1NwZWMpOwogICAgU2VuZF9LQUhMX01PRF9BRShidWYpOwp9CiNlbmRpZgoKI2lmZGVmIEZFQVRfVElUTEUKLyoKICogU2V0IHRoZSB3aW5kb3cgdGl0bGUgYW5kIGljb24uCiAqIChUaGUgaWNvbiBpcyBub3QgdGFrZW4gY2FyZSBvZikuCiAqLwogICAgdm9pZApndWlfbWNoX3NldHRpdGxlKGNoYXJfdSAqdGl0bGUsIGNoYXJfdSAqaWNvbikKewogICAgLyogVE9ETzogR2V0IHZpbSB0byBtYWtlIHN1cmUgbWF4bGVuIChmcm9tIHBfdGl0bGVsZW4pIGlzIHNtYWxsZXIKICAgICAqICAgICAgIHRoYXQgMjU2LiBFdmVuIGJldHRlciBnZXQgaXQgdG8gZml0IG5pY2VseSBpbiB0aGUgdGl0bGViYXIuCiAgICAgKi8KI2lmZGVmIE1BQ09TX0NPTlZFUlQKICAgIENGU3RyaW5nUmVmIHdpbmRvd1RpdGxlOwogICAgc2l6ZV90CXdpbmRvd1RpdGxlTGVuOwojZWxzZQogICAgY2hhcl91ICAgKnBhc2NhbFRpdGxlOwojZW5kaWYKCiAgICBpZiAodGl0bGUgPT0gTlVMTCkJCS8qIG5vdGhpbmcgdG8gZG8gKi8KCXJldHVybjsKCiNpZmRlZiBNQUNPU19DT05WRVJUCiAgICB3aW5kb3dUaXRsZUxlbiA9IFNUUkxFTih0aXRsZSk7CiAgICB3aW5kb3dUaXRsZSAgPSBtYWNfZW5jX3RvX2Nmc3RyaW5nKHRpdGxlLCB3aW5kb3dUaXRsZUxlbik7CgogICAgaWYgKHdpbmRvd1RpdGxlKQogICAgewoJU2V0V2luZG93VGl0bGVXaXRoQ0ZTdHJpbmcoZ3VpLlZpbVdpbmRvdywgd2luZG93VGl0bGUpOwoJQ0ZSZWxlYXNlKHdpbmRvd1RpdGxlKTsKICAgIH0KI2Vsc2UKICAgIHBhc2NhbFRpdGxlID0gQzJQYXNjYWxfc2F2ZSh0aXRsZSk7CiAgICBpZiAocGFzY2FsVGl0bGUgIT0gTlVMTCkKICAgIHsKCVNldFdUaXRsZShndWkuVmltV2luZG93LCBwYXNjYWxUaXRsZSk7Cgl2aW1fZnJlZShwYXNjYWxUaXRsZSk7CiAgICB9CiNlbmRpZgp9CiNlbmRpZgoKLyoKICogVHJhbnNmZXJlZCBmcm9tIG9zX21hYy5jIGZvciBNYWNPUyBYIHVzaW5nIG9zX3VuaXguYyBwcmVwIHdvcmsKICovCgogICAgaW50CkMyUGFzY2FsU3RyaW5nKGNoYXJfdSAqQ1N0cmluZywgU3RyMjU1ICpQYXNjYWxTdHJpbmcpCnsKICAgIGNoYXJfdSAqUGFzY2FsUHRyID0gKGNoYXJfdSAqKSBQYXNjYWxTdHJpbmc7CiAgICBpbnQgICAgbGVuOwogICAgaW50ICAgIGk7CgogICAgUGFzY2FsUHRyWzBdID0gMDsKICAgIGlmIChDU3RyaW5nID09IE5VTEwpCglyZXR1cm4gMDsKCiAgICBsZW4gPSBTVFJMRU4oQ1N0cmluZyk7CiAgICBpZiAobGVuID4gMjU1KQoJbGVuID0gMjU1OwoKICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykKCVBhc2NhbFB0cltpKzFdID0gQ1N0cmluZ1tpXTsKCiAgICBQYXNjYWxQdHJbMF0gPSBsZW47CgogICAgcmV0dXJuIDA7Cn0KCiAgICBpbnQKR2V0RlNTcGVjRnJvbVBhdGgoY2hhcl91ICpmaWxlLCBGU1NwZWMgKmZpbGVGU1NwZWMpCnsKICAgIC8qIEZyb20gRkFRIDgtMTIgKi8KICAgIFN0cjI1NSAgICAgIGZpbGVQYXNjYWw7CiAgICBDSW5mb1BCUmVjCW15Q1BCOwogICAgT1NFcnIJZXJyOwoKICAgICh2b2lkKSBDMlBhc2NhbFN0cmluZyhmaWxlLCAmZmlsZVBhc2NhbCk7CgogICAgbXlDUEIuZGlySW5mby5pb05hbWVQdHIgICA9IGZpbGVQYXNjYWw7CiAgICBteUNQQi5kaXJJbmZvLmlvVlJlZk51bSAgID0gMDsKICAgIG15Q1BCLmRpckluZm8uaW9GRGlySW5kZXggPSAwOwogICAgbXlDUEIuZGlySW5mby5pb0RyRGlySUQgICA9IDA7CgogICAgZXJyPSBQQkdldENhdEluZm8oJm15Q1BCLCBmYWxzZSk7CgogICAgLyogICAgdlJlZk51bSwgZGlySUQsIG5hbWUgKi8KICAgIEZTTWFrZUZTU3BlYygwLCAwLCBmaWxlUGFzY2FsLCBmaWxlRlNTcGVjKTsKCiAgICAvKiBUT0RPOiBVc2UgYW4gZXJyb3IgY29kZSBtZWNoYW5pc20gKi8KICAgIHJldHVybiAwOwp9CgovKgogKiBDb252ZXJ0IGEgRlNTcGVjIHRvIGEgZnVpbGwgcGF0aAogKi8KCmNoYXJfdSAqRnVsbFBhdGhGcm9tRlNTcGVjX3NhdmUoRlNTcGVjIGZpbGUpCnsKICAgIC8qCiAgICAgKiBUT0RPOiBBZGQgcHJvdGVjdGlvbiBmb3IgMjU2IGNoYXIgbWF4LgogICAgICovCgogICAgQ0luZm9QQlJlYwl0aGVDUEI7CiAgICBjaGFyX3UJZm5hbWVbMjU2XTsKICAgIGNoYXJfdQkqZmlsZW5hbWVQdHIgPSBmbmFtZTsKICAgIE9TRXJyCWVycm9yOwogICAgaW50CQlmb2xkZXIgPSAxOwojaWZkZWYgVVNFX1VOSVhGSUxFTkFNRQogICAgU0ludDE2CWRmbHRWb2xfdlJlZk51bTsKICAgIFNJbnQzMglkZmx0Vm9sX2RpcklEOwogICAgRlNSZWYJcmVmRmlsZTsKICAgIE9TU3RhdHVzCXN0YXR1czsKICAgIFVJbnQzMglwYXRoU2l6ZSA9IDI1NjsKICAgIGNoYXJfdQlwYXRobmFtZVsyNTZdOwogICAgY2hhcl91CSpwYXRoID0gcGF0aG5hbWU7CiNlbHNlCiAgICBTdHIyNTUJZGlyZWN0b3J5TmFtZTsKICAgIGNoYXJfdQl0ZW1wb3JhcnlbMjU1XTsKICAgIGNoYXJfdQkqdGVtcG9yYXJ5UHRyID0gdGVtcG9yYXJ5OwojZW5kaWYKCiNpZmRlZiBVU0VfVU5JWEZJTEVOQU1FCiAgICAvKiBHZXQgdGhlIGRlZmF1bHQgdm9sdW1lICovCiAgICAvKiBUT0RPOiBSZW1vdmUgYXMgdGhpcyBvbmx5IHdvcmsgaWYgVmltIGlzIG9uIHRoZSBCb290IFZvbHVtZSovCiAgICBlcnJvcj1IR2V0Vm9sKE5VTEwsICZkZmx0Vm9sX3ZSZWZOdW0sICZkZmx0Vm9sX2RpcklEKTsKCiAgICBpZiAoZXJyb3IpCiAgICAgIHJldHVybiBOVUxMOwojZW5kaWYKCiAgICAvKiBTdGFydCBmaWxsaW5nIGZuYW1lIHdpdGggZmlsZS5uYW1lICAqLwogICAgdmltX3N0cm5jcHkoZmlsZW5hbWVQdHIsICZmaWxlLm5hbWVbMV0sIGZpbGUubmFtZVswXSk7CgogICAgLyogR2V0IHRoZSBpbmZvIGFib3V0IHRoZSBmaWxlIHNwZWNpZmllZCBpbiBGU1NwZWMgKi8KICAgIHRoZUNQQi5kaXJJbmZvLmlvRkRpckluZGV4ID0gMDsKICAgIHRoZUNQQi5kaXJJbmZvLmlvTmFtZVB0ciAgID0gZmlsZS5uYW1lOwogICAgdGhlQ1BCLmRpckluZm8uaW9WUmVmTnVtICAgPSBmaWxlLnZSZWZOdW07CiAgLyp0aGVDUEIuaEZpbGVJbmZvLmlvRGlySUQgICA9IDA7Ki8KICAgIHRoZUNQQi5kaXJJbmZvLmlvRHJEaXJJRCAgID0gZmlsZS5wYXJJRDsKCiAgICAvKiBBcyBpb0ZEaXJJbmRleCA9IDAsIGdldCB0aGUgaW5mbyBvZiBpb05hbWVQdHIsCiAgICAgICB3aGljaCBpcyByZWxhdGl2ZSB0byBpb1ZyZWZOdW0sIGlvRGlySUQgKi8KICAgIGVycm9yID0gUEJHZXRDYXRJbmZvKCZ0aGVDUEIsIGZhbHNlKTsKCiAgICAvKiBJZiB3ZSBhcmUgY2FsbGVkIGZvciBhIG5ldyBmaWxlIHdlIGV4cGVjdCBmbmZFcnIgKi8KICAgIGlmICgoZXJyb3IpICYmIChlcnJvciAhPSBmbmZFcnIpKQogICAgICByZXR1cm4gTlVMTDsKCiAgICAvKiBDaGVjayBpZiBpdCdzIGEgZmlsZSBvciBmb2xkZXIgICAgICAgKi8KICAgIC8qIGRlZmF1bHQgdG8gZmlsZSBpZiBmaWxlIGRvbid0IGV4aXN0ICAqLwogICAgaWYgKCgodGhlQ1BCLmhGaWxlSW5mby5pb0ZsQXR0cmliICYgaW9EaXJNYXNrKSA9PSAwKSB8fCAoZXJyb3IpKQogICAgICBmb2xkZXIgPSAwOyAvKiBJdCdzIG5vdCBhIGZvbGRlciAqLwogICAgZWxzZQogICAgICBmb2xkZXIgPSAxOwoKI2lmZGVmIFVTRV9VTklYRklMRU5BTUUKICAgIC8qCiAgICAgKiBUaGUgZnVuY3Rpb24gdXNlZCBoZXJlIGFyZSBhdmFpbGFibGUgaW4gQ2FyYm9uLCBidXQKICAgICAqIGRvIG5vdGhpbmcgdW5lIE1hY09TIDggYW5kIDkKICAgICAqLwogICAgaWYgKGVycm9yID09IGZuZkVycikKICAgIHsKCS8qIElmIHRoZSBmaWxlIHRvIGJlIHNhdmVkIGRvZXMgbm90IGFscmVhZHkgZXhpc3QsIGl0IGlzbid0IHBvc3NpYmxlCgkgICB0byBjb252ZXJ0IGl0cyBGU1NwZWMgaW50byBhbiBGU1JlZi4gIEJ1dCB3ZSBjYW4gY29uc3RydWN0IGFuCgkgICBGU1NwZWMgZm9yIHRoZSBmaWxlJ3MgcGFyZW50IGZvbGRlciAoc2luY2Ugd2UgaGF2ZSBpdHMgdm9sdW1lIGFuZAoJICAgZGlyZWN0b3J5IElEcyksIGFuZCBzaW5jZSB0aGF0IGZvbGRlciBkb2VzIGV4aXN0LCB3ZSBjYW4gY29udmVydAoJICAgdGhhdCBGU1NwZWMgaW50byBhbiBGU1JlZiwgY29udmVydCB0aGUgRlNSZWYgaW4gdHVybiBpbnRvIGEgcGF0aCwKCSAgIGFuZCwgZmluYWxseSwgYXBwZW5kIHRoZSBmaWxlbmFtZS4gKi8KCUZTU3BlYyBkaXJTcGVjOwoJRlNSZWYgZGlyUmVmOwoJU3RyMjU1IGVtcHR5RmlsZW5hbWUgPSAiXHAiOwoJZXJyb3IgPSBGU01ha2VGU1NwZWModGhlQ1BCLmRpckluZm8uaW9WUmVmTnVtLAoJICAgIHRoZUNQQi5kaXJJbmZvLmlvRHJEaXJJRCwgZW1wdHlGaWxlbmFtZSwgJmRpclNwZWMpOwoJaWYgKGVycm9yKQoJICAgIHJldHVybiBOVUxMOwoKCWVycm9yID0gRlNwTWFrZUZTUmVmKCZkaXJTcGVjLCAmZGlyUmVmKTsKCWlmIChlcnJvcikKCSAgICByZXR1cm4gTlVMTDsKCglzdGF0dXMgPSBGU1JlZk1ha2VQYXRoKCZkaXJSZWYsIChVSW50OCopcGF0aCwgcGF0aFNpemUpOwoJaWYgKHN0YXR1cykKCSAgICByZXR1cm4gTlVMTDsKCglTVFJDQVQocGF0aCwgIi8iKTsKCVNUUkNBVChwYXRoLCBmaWxlbmFtZVB0cik7CiAgICB9CiAgICBlbHNlCiAgICB7CgkvKiBJZiB0aGUgZmlsZSB0byBiZSBzYXZlZCBhbHJlYWR5IGV4aXN0cywgd2UgY2FuIGdldCBpdHMgZnVsbCBwYXRoCgkgICBieSBjb252ZXJ0aW5nIGl0cyBGU1NwZWMgaW50byBhbiBGU1JlZi4gKi8KCWVycm9yPUZTcE1ha2VGU1JlZigmZmlsZSwgJnJlZkZpbGUpOwoJaWYgKGVycm9yKQoJICAgIHJldHVybiBOVUxMOwoKCXN0YXR1cz1GU1JlZk1ha2VQYXRoKCZyZWZGaWxlLCAoVUludDggKikgcGF0aCwgcGF0aFNpemUpOwoJaWYgKHN0YXR1cykKCSAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBBZGQgYSBzbGFzaCBhdCB0aGUgZW5kIGlmIG5lZWRlZCAqLwogICAgaWYgKGZvbGRlcikKCVNUUkNBVChwYXRoLCAiLyIpOwoKICAgIHJldHVybiAodmltX3N0cnNhdmUocGF0aCkpOwojZWxzZQogICAgLyogVE9ETzogR2V0IHJpZCBvZiBhbGwgVVNFX1VOSVhGSUxFTkFNRSBiZWxvdyAqLwogICAgLyogU2V0IGlvTmFtZVB0ciwgaXQncyB0aGUgc2FtZSBhcmVhIHdoaWNoIGlzIGFsd2F5cyByZXVzZWQuICovCiAgICB0aGVDUEIuZGlySW5mby5pb05hbWVQdHIgPSBkaXJlY3RvcnlOYW1lOwoKICAgIC8qIFRyaWNrIGZvciBmaXJzdCBlbnRyeSwgc2V0IGlvRHJQYXJJRCB0byB0aGUgZmlyc3QgdmFsdWUKICAgICAqIHdlIHdhbnQgZm9yIGlvRHJEaXJJRCovCiAgICB0aGVDUEIuZGlySW5mby5pb0RyUGFySUQgPSBmaWxlLnBhcklEOwogICAgdGhlQ1BCLmRpckluZm8uaW9EckRpcklEID0gZmlsZS5wYXJJRDsKCiAgICBpZiAoKFRSVUUpICYmIChmaWxlLnBhcklEICE9IGZzUnREaXJJRCAvKmZzUnRQYXJJRCovKSkKICAgIGRvCiAgICB7Cgl0aGVDUEIuZGlySW5mby5pb0ZEaXJJbmRleCA9IC0xOwogICAgIC8qIHRoZUNQQi5kaXJJbmZvLmlvTmFtZVB0ciAgID0gZGlyZWN0b3J5TmFtZTsgQWxyZWFkeSBkb25lIGFib3ZlLiAqLwoJdGhlQ1BCLmRpckluZm8uaW9WUmVmTnVtICAgPSBmaWxlLnZSZWZOdW07CiAgICAgLyogdGhlQ1BCLmRpckluZm8uaW9EaXJJRCAgICAgPSBpcnJldmVsYW50IHdoZW4gaW9GRGlySW5kZXggPSAtMSAqLwoJdGhlQ1BCLmRpckluZm8uaW9EckRpcklEICAgPSB0aGVDUEIuZGlySW5mby5pb0RyUGFySUQ7CgoJLyogQXMgaW9GRGlySW5kZXggPSAtMSwgZ2V0IHRoZSBpbmZvIG9mIGlvRHJEaXJJRCwgKi8KCS8qICAqaW9OYW1lUHRyWzAgVE8gMzFdIHdpbGwgYmUgdXBkYXRlZAkJICAgKi8KCWVycm9yID0gUEJHZXRDYXRJbmZvKCZ0aGVDUEIsZmFsc2UpOwoKCWlmIChlcnJvcikKCSAgcmV0dXJuIE5VTEw7CgoJLyogUHV0IHRoZSBuZXcgZGlyZWN0b3J5TmFtZSBpbiBmcm9udCBvZiB0aGUgY3VycmVudCBmbmFtZSAqLwoJU1RSQ1BZKHRlbXBvcmFyeVB0ciwgZmlsZW5hbWVQdHIpOwoJdmltX3N0cm5jcHkoZmlsZW5hbWVQdHIsICZkaXJlY3RvcnlOYW1lWzFdLCBkaXJlY3RvcnlOYW1lWzBdKTsKCVNUUkNBVChmaWxlbmFtZVB0ciwgIjoiKTsKCVNUUkNBVChmaWxlbmFtZVB0ciwgdGVtcG9yYXJ5UHRyKTsKICAgIH0KI2lmIDEgLyogZGVmIFVTRV9VTklYRklMRU5BTUUgKi8KICAgIHdoaWxlICgodGhlQ1BCLmRpckluZm8uaW9EclBhcklEICE9IGZzUnREaXJJRCkgLyogJiYgKi8KCSAvKiAgKHRoZUNQQi5kaXJJbmZvLmlvRHJEaXJJRCAhPSBmc1J0RGlySUQpKi8pOwojZWxzZQogICAgd2hpbGUgKHRoZUNQQi5kaXJJbmZvLmlvRHJEaXJJRCAhPSBmc1J0RGlySUQpOwojZW5kaWYKCiAgICAvKiBHZXQgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSB2b2x1bWUgb24gd2hpY2ggdGhlIGZpbGUgcmVzaWRlICovCiAgICB0aGVDUEIuZGlySW5mby5pb0ZEaXJJbmRleCA9IC0xOwogLyogdGhlQ1BCLmRpckluZm8uaW9OYW1lUHRyICAgPSBkaXJlY3RvcnlOYW1lOyBBbHJlYWR5IGRvbmUgYWJvdmUuICovCiAgICB0aGVDUEIuZGlySW5mby5pb1ZSZWZOdW0gICA9IGZpbGUudlJlZk51bTsKIC8qIHRoZUNQQi5kaXJJbmZvLmlvRGlySUQgICAgID0gaXJyZXZlbGFudCB3aGVuIGlvRkRpckluZGV4ID0gLTEgKi8KICAgIHRoZUNQQi5kaXJJbmZvLmlvRHJEaXJJRCAgID0gdGhlQ1BCLmRpckluZm8uaW9EclBhcklEOwoKICAgIC8qIEFzIGlvRkRpckluZGV4ID0gLTEsIGdldCB0aGUgaW5mbyBvZiBpb0RyRGlySUQsICovCiAgICAvKgkqaW9OYW1lUHRyWzAgVE8gMzFdIHdpbGwgYmUgdXBkYXRlZAkgICAgICAgKi8KICAgIGVycm9yID0gUEJHZXRDYXRJbmZvKCZ0aGVDUEIsZmFsc2UpOwoKICAgIGlmIChlcnJvcikKICAgICAgcmV0dXJuIE5VTEw7CgogICAgLyogRm9yIE1hY09TIENsYXNzaWMgYWx3YXlzIGFkZCB0aGUgdm9sdW1lIG5hbWUJICAgICAqLwogICAgLyogRm9yIE1hY09TIFggYWRkIHRoZSB2b2x1bWUgbmFtZSBwcmVjZWRlZCBieSAiVm9sdW1lcyIgKi8KICAgIC8qCXdoZW4gd2UgYXJlIG5vdCByZWZlcmluZyB0byB0aGUgYm9vdCB2b2x1bWUJICAgICAqLwojaWZkZWYgVVNFX1VOSVhGSUxFTkFNRQogICAgaWYgKGZpbGUudlJlZk51bSAhPSBkZmx0Vm9sX3ZSZWZOdW0pCiNlbmRpZgogICAgewoJLyogQWRkIHRoZSB2b2x1bWUgbmFtZSAqLwoJU1RSQ1BZKHRlbXBvcmFyeVB0ciwgZmlsZW5hbWVQdHIpOwoJdmltX3N0cm5jcHkoZmlsZW5hbWVQdHIsICZkaXJlY3RvcnlOYW1lWzFdLCBkaXJlY3RvcnlOYW1lWzBdKTsKCVNUUkNBVChmaWxlbmFtZVB0ciwgIjoiKTsKCVNUUkNBVChmaWxlbmFtZVB0ciwgdGVtcG9yYXJ5UHRyKTsKCiNpZmRlZiBVU0VfVU5JWEZJTEVOQU1FCglTVFJDUFkodGVtcG9yYXJ5UHRyLCBmaWxlbmFtZVB0cik7CglmaWxlbmFtZVB0clswXSA9IDA7IC8qIE5VTEwgdGVybWluYXRlIHRoZSBzdHJpbmcgKi8KCVNUUkNBVChmaWxlbmFtZVB0ciwgIlZvbHVtZXM6Iik7CglTVFJDQVQoZmlsZW5hbWVQdHIsIHRlbXBvcmFyeVB0cik7CiNlbmRpZgogICAgfQoKICAgIC8qIEFwcGVuZCBmaW5hbCBwYXRoIHNlcGFyYXRvciBpZiBpdCdzIGEgZm9sZGVyICovCiAgICBpZiAoZm9sZGVyKQoJU1RSQ0FUKGZuYW1lLCAiOiIpOwoKICAgIC8qIEFzIHdlIHVzZSBVbml4IEZpbGUgTmFtZSBmb3IgTWFjT1MgWCBjb252ZXJ0IGl0ICovCiNpZmRlZiBVU0VfVU5JWEZJTEVOQU1FCiAgICAvKiBOZWVkIHRvIGluc2VydCBsZWFkaW5nIC8gKi8KICAgIC8qIFRPRE86IGdldCB0aGUgYWJvdmUgY29kZSB0byB1c2UgZGlyZWN0bHkgdGhlIC8gKi8KICAgIFNUUkNQWSgmdGVtcG9yYXJ5UHRyWzFdLCBmaWxlbmFtZVB0cik7CiAgICB0ZW1wb3JhcnlQdHJbMF0gPSAnLyc7CiAgICBTVFJDUFkoZmlsZW5hbWVQdHIsIHRlbXBvcmFyeVB0cik7CiAgICB7CiAgICBjaGFyCSpwOwogICAgZm9yIChwID0gZm5hbWU7ICpwOyBwKyspCglpZiAoKnAgPT0gJzonKQoJICAgICpwID0gJy8nOwogICAgfQojZW5kaWYKCiAgICByZXR1cm4gKHZpbV9zdHJzYXZlKGZuYW1lKSk7CiNlbmRpZgp9CgojaWYgZGVmaW5lZChVU0VfSU1fQ09OVFJPTCkgfHwgZGVmaW5lZChQUk9UTykKLyoKICogSW5wdXQgTWV0aG9kIENvbnRyb2wgZnVuY3Rpb25zLgogKi8KCi8qCiAqIE5vdGlmeSBjdXJzb3IgcG9zaXRpb24gdG8gSU0uCiAqLwogICAgdm9pZAppbV9zZXRfcG9zaXRpb24oaW50IHJvdywgaW50IGNvbCkKewogICAgLyogVE9ETzogSW1wbGVtZW50IG1lISAqLwp9CgovKgogKiBTZXQgSU0gc3RhdHVzIG9uICgiYWN0aXZlIiBpcyBUUlVFKSBvciBvZmYgKCJhY3RpdmUiIGlzIEZBTFNFKS4KICovCiAgICB2b2lkCmltX3NldF9hY3RpdmUoaW50IGFjdGl2ZSkKewogICAgS2V5U2NyaXB0KGFjdGl2ZSA/IHNtS2V5U3lzU2NyaXB0IDogc21LZXlSb21hbik7Cn0KCi8qCiAqIEdldCBJTSBzdGF0dXMuICBXaGVuIElNIGlzIG9uLCByZXR1cm4gbm90IDAuICBFbHNlIHJldHVybiAwLgogKi8KICAgIGludAppbV9nZXRfc3RhdHVzKHZvaWQpCnsKICAgIFNJbnQzMiBzY3JpcHQgPSBHZXRTY3JpcHRNYW5hZ2VyVmFyaWFibGUoc21LZXlTY3JpcHQpOwogICAgcmV0dXJuIChzY3JpcHQgIT0gc21Sb21hbgoJICAgICYmIHNjcmlwdCA9PSBHZXRTY3JpcHRNYW5hZ2VyVmFyaWFibGUoc21TeXNTY3JpcHQpKSA/IDEgOiAwOwp9CiNlbmRpZiAvKiBkZWZpbmVkKFVTRV9JTV9DT05UUk9MKSB8fCBkZWZpbmVkKFBST1RPKSAqLwo=