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+d2hlcmU7CiAgICBHbG9iYWxUb0xvY2FsKCZ0aGVQb2ludCk7CgogICAgdmltTW9kaWZpZXJzID0gRXZlbnRNb2RpZmllcnMyVmltTW91c2VNb2RpZmllcnModGhlRXZlbnQtPm1vZGlmaWVycyk7CiAgICBpZiAoY2xpY2tJc1BvcHVwKQogICAgewoJdmltTW9kaWZpZXJzICY9IH5NT1VTRV9DVFJMOwoJY2xpY2tJc1BvcHVwID0gRkFMU0U7CiAgICB9CiAgICBndWlfc2VuZF9tb3VzZV9ldmVudChNT1VTRV9SRUxFQVNFLCB0aGVQb2ludC5oLCB0aGVQb2ludC52LCBGQUxTRSwgdmltTW9kaWZpZXJzKTsKfQoKICAgIHN0YXRpYyBwYXNjYWwgT1NTdGF0dXMKZ3VpX21hY19tb3VzZV93aGVlbChFdmVudEhhbmRsZXJDYWxsUmVmIG5leHRIYW5kbGVyLCBFdmVudFJlZiB0aGVFdmVudCwKCQkJCQkJCQkgICB2b2lkICpkYXRhKQp7CiAgICBFdmVudFJlZglib2d1c0V2ZW50OwogICAgUG9pbnQJcG9pbnQ7CiAgICBSZWN0CWJvdW5kczsKICAgIFVJbnQzMgltb2Q7CiAgICBTSW50MzIJZGVsdGE7CiAgICBpbnRfdQl2aW1fbW9kOwogICAgRXZlbnRNb3VzZVdoZWVsQXhpcyBheGlzOwoKICAgIGlmIChub0VyciA9PSBHZXRFdmVudFBhcmFtZXRlcih0aGVFdmVudCwga0V2ZW50UGFyYW1Nb3VzZVdoZWVsQXhpcywKCQkJICB0eXBlTW91c2VXaGVlbEF4aXMsIE5VTEwsIHNpemVvZihheGlzKSwgTlVMTCwgJmF4aXMpCgkgICAgJiYgYXhpcyAhPSBrRXZlbnRNb3VzZVdoZWVsQXhpc1kpCglnb3RvIGJhaWw7IC8qIFZpbSBvbmx5IGRvZXMgdXAtZG93biBzY3JvbGxpbmcgKi8KCiAgICBpZiAobm9FcnIgIT0gR2V0RXZlbnRQYXJhbWV0ZXIodGhlRXZlbnQsIGtFdmVudFBhcmFtTW91c2VXaGVlbERlbHRhLAoJCQkgICAgICB0eXBlU0ludDMyLCBOVUxMLCBzaXplb2YoU0ludDMyKSwgTlVMTCwgJmRlbHRhKSkKCWdvdG8gYmFpbDsKICAgIGlmIChub0VyciAhPSBHZXRFdmVudFBhcmFtZXRlcih0aGVFdmVudCwga0V2ZW50UGFyYW1Nb3VzZUxvY2F0aW9uLAoJCQkgICAgICB0eXBlUURQb2ludCwgTlVMTCwgc2l6ZW9mKFBvaW50KSwgTlVMTCwgJnBvaW50KSkKCWdvdG8gYmFpbDsKICAgIGlmIChub0VyciAhPSBHZXRFdmVudFBhcmFtZXRlcih0aGVFdmVudCwga0V2ZW50UGFyYW1LZXlNb2RpZmllcnMsCgkJCQl0eXBlVUludDMyLCBOVUxMLCBzaXplb2YoVUludDMyKSwgTlVMTCwgJm1vZCkpCglnb3RvIGJhaWw7CgogICAgdmltX21vZCA9IDA7CiAgICBpZiAobW9kICYgc2hpZnRLZXkpCgl2aW1fbW9kIHw9IE1PVVNFX1NISUZUOwogICAgaWYgKG1vZCAmIGNvbnRyb2xLZXkpCgl2aW1fbW9kIHw9IE1PVVNFX0NUUkw7CiAgICBpZiAobW9kICYgb3B0aW9uS2V5KQoJdmltX21vZCB8PSBNT1VTRV9BTFQ7CgogICAgLyogcG9zdCBhIGJvZ3VzIGV2ZW50IHRvIHdha2UgdXAgV2FpdE5leHRFdmVudCAqLwogICAgaWYgKG5vRXJyICE9IENyZWF0ZUV2ZW50KE5VTEwsIGtFdmVudENsYXNzTW91c2UsIGtFdmVudE1vdXNlTW92ZWQsIDAsCgkJCQkJICAgIGtFdmVudEF0dHJpYnV0ZU5vbmUsICZib2d1c0V2ZW50KSkKCWdvdG8gYmFpbDsKICAgIGlmIChub0VyciAhPSBQb3N0RXZlbnRUb1F1ZXVlKEdldE1haW5FdmVudFF1ZXVlKCksIGJvZ3VzRXZlbnQsCgkJCQkJCQkgICBrRXZlbnRQcmlvcml0eUxvdykpCglnb3RvIGJhaWw7CgogICAgUmVsZWFzZUV2ZW50KGJvZ3VzRXZlbnQpOwoKICAgIGlmIChub0VyciA9PSBHZXRXaW5kb3dCb3VuZHMoZ3VpLlZpbVdpbmRvdywga1dpbmRvd0NvbnRlbnRSZ24sICZib3VuZHMpKQogICAgewoJcG9pbnQuaCAtPSBib3VuZHMubGVmdDsKCXBvaW50LnYgLT0gYm91bmRzLnRvcDsKICAgIH0KCiAgICBndWlfc2VuZF9tb3VzZV9ldmVudCgoZGVsdGEgPiAwKSA/IE1PVVNFXzQgOiBNT1VTRV81LAoJCQkJCSAgICBwb2ludC5oLCBwb2ludC52LCBGQUxTRSwgdmltX21vZCk7CgogICAgcmV0dXJuIG5vRXJyOwoKICBiYWlsOgogICAgLyoKICAgICAqIHdoZW4gd2UgZmFpbCBnaXZlIGFueSBhZGRpdGlvbmFsIGNhbGxiYWNrIGhhbmRsZXIgYSBjaGFuY2UgdG8gcGVyZm9ybQogICAgICogaXQncyBhY3Rpb25zCiAgICAgKi8KICAgIHJldHVybiBDYWxsTmV4dEV2ZW50SGFuZGxlcihuZXh0SGFuZGxlciwgdGhlRXZlbnQpOwp9CgojaWYgMAoKLyoKICogVGhpcyB3b3VsZCBiZSB0aGUgbm9ybWFsIHdheSBvZiBpbnZva2luZyB0aGUgY29udGV4dHVhbCBtZW51CiAqIGJ1dCB0aGUgVmltIEFQSSBkb2Vzbid0IHNlZW0gdG8gYSBzdXBwb3J0IGEgcmVxdWVzdCB0byBnZXQKICogdGhlIG1lbnUgdGhhdCB3ZSBzaG91bGQgZGlzcGxheQogKi8KICAgIHZvaWQKZ3VpX21hY19oYW5kbGVfY29udGV4dHVhbF9tZW51KGV2ZW50KQogICAgRXZlbnRSZWNvcmQgKmV2ZW50Owp7Ci8qCiAqICBDbG9uZSBQb3BVcCB0byB1c2UgbWVudQogKiAgQ3JlYXRlIGEgb2JqZWN0IGRlc2NyaXB0b3IgZm9yIHRoZSBjdXJyZW50IHNlbGVjdGlvbgogKiAgQ2FsbCB0aGUgcHJvY2VkdXJlCiAqLwoKLy8gIENhbGwgdG8gSGFuZGxlIFBvcHVwCiAgICBPU1N0YXR1cyBzdGF0dXMgPSBDb250ZXh0dWFsTWVudVNlbGVjdChDbnR4TWVudSwgZXZlbnQtPndoZXJlLCBmYWxzZSwga0NNSGVscEl0ZW1Ob0hlbHAsICIiLCBOVUxMLCAmQ250eFR5cGUsICZDbnR4TWVudUlELCAmQ250eE1lbnVJdGVtKTsKCiAgICBpZiAoc3RhdHVzICE9IG5vRXJyKQoJcmV0dXJuOwoKICAgIGlmIChDbnR4VHlwZSA9PSBrQ01NZW51SXRlbVNlbGVjdGVkKQogICAgewoJLyogSGFuZGxlIHRoZSBtZW51IENudHhNZW51SUQsIENudHhNZW51SXRlbSAqLwoJLyogVGhlIHN1Ym1lbnUgY2FuIGJlIGhhbmRsZSBkaXJlY3RseSBieSBndWlfbWFjX2hhbmRsZV9tZW51ICovCgkvKiBCdXQgd2hhdCBhYm91dCB0aGUgY3VycmVudCBtZW51LCBpcyB0aGUgbWVueSBjaGFuZ2VkIGJ5IENvbnRleHR1YWxNZW51U2VsZWN0ICovCglndWlfbWFjX2hhbmRsZV9tZW51KChDbnR4TWVudUlEIDw8IDE2KSArIENudHhNZW51SXRlbSk7CiAgICB9CiAgICBlbHNlIGlmIChDbnR4TWVudUlEID09IGtDTVNob3dIZWxwU2VsZWN0ZWQpCiAgICB7CgkvKiBTaG91bGQgY29tZSB1cCB3aXRoIHRoZSBoZWxwICovCiAgICB9Cgp9CiNlbmRpZgoKLyoKICogSGFuZGxlIG1lbnViYXIgc2VsZWN0aW9uCiAqLwogICAgdm9pZApndWlfbWFjX2hhbmRsZV9tZW51KGxvbmcgbWVudUNob2ljZSkKewogICAgc2hvcnQJbWVudSA9IEhpV29yZChtZW51Q2hvaWNlKTsKICAgIHNob3J0CWl0ZW0gPSBMb1dvcmQobWVudUNob2ljZSk7CiAgICB2aW1tZW51X1QJKnRoZVZpbU1lbnUgPSByb290X21lbnU7CgogICAgaWYgKG1lbnUgPT0gMjU2KSAgLyogVE9ETzogdXNlIGNvbnN0YW50IG9yIGd1aS54eXogKi8KICAgIHsKCWlmIChpdGVtID09IDEpCgkgICAgZ3VpX21jaF9iZWVwKCk7IC8qIFRPRE86IFBvcHVwIGRpYWxvZyBvciBkbyA6aW50cm8gKi8KICAgIH0KICAgIGVsc2UgaWYgKGl0ZW0gIT0gMCkKICAgIHsKCXRoZVZpbU1lbnUgPSBndWlfbWFjX2dldF92aW1fbWVudShtZW51LCBpdGVtLCByb290X21lbnUpOwoKCWlmICh0aGVWaW1NZW51KQoJICAgIGd1aV9tZW51X2NiKHRoZVZpbU1lbnUpOwogICAgfQogICAgSGlsaXRlTWVudSgwKTsKfQoKLyoKICogRGlzcGF0Y2ggdGhlIGV2ZW50IHRvIHByb3BlciBoYW5kbGVyCiAqLwoKICAgIHZvaWQKZ3VpX21hY19oYW5kbGVfZXZlbnQoRXZlbnRSZWNvcmQgKmV2ZW50KQp7CiAgICBPU0VycgllcnJvcjsKCiAgICAvKiBIYW5kbGUgY29udGV4dHVhbCBtZW51IHJpZ2h0IG5vdyAoaWYgbmVlZGVkKSAqLwogICAgaWYgKGd1aS5NYWNPU0hhdmVDbnR4TWVudSkKCWlmIChJc1Nob3dDb250ZXh0dWFsTWVudUNsaWNrKGV2ZW50KSkKCXsKIyBpZiAwCgkgICAgZ3VpX21hY19oYW5kbGVfY29udGV4dHVhbF9tZW51KGV2ZW50KTsKIyBlbHNlCgkgICAgZ3VpX21hY19kb01vdXNlRG93bkV2ZW50KGV2ZW50KTsKIyBlbmRpZgoJICAgIHJldHVybjsKCX0KCiAgICAvKiBIYW5kbGUgbm9ybWFsIGV2ZW50ICovCiAgICBzd2l0Y2ggKGV2ZW50LT53aGF0KQogICAgewojaWZuZGVmIFVTRV9DQVJCT05LRVlIQU5ETEVSCgljYXNlIChrZXlEb3duKToKCWNhc2UgKGF1dG9LZXkpOgoJICAgIGd1aV9tYWNfZG9LZXlFdmVudChldmVudCk7CgkgICAgYnJlYWs7CiNlbmRpZgoJY2FzZSAoa2V5VXApOgoJICAgIC8qIFdlIGRvbid0IGNhcmUgYWJvdXQgd2hlbiB0aGUga2V5IGlzIHJlbGVhc2VkICovCgkgICAgYnJlYWs7CgoJY2FzZSAobW91c2VEb3duKToKCSAgICBndWlfbWFjX2RvTW91c2VEb3duRXZlbnQoZXZlbnQpOwoJICAgIGJyZWFrOwoKCWNhc2UgKG1vdXNlVXApOgoJICAgIGd1aV9tYWNfZG9Nb3VzZVVwRXZlbnQoZXZlbnQpOwoJICAgIGJyZWFrOwoKCWNhc2UgKHVwZGF0ZUV2dCk6CgkgICAgZ3VpX21hY19kb1VwZGF0ZUV2ZW50KGV2ZW50KTsKCSAgICBicmVhazsKCgljYXNlIChkaXNrRXZ0KToKCSAgICAvKiBXZSBkb24ndCBuZWVkIHNwZWNpYWwgaGFuZGxpbmcgZm9yIGRpc2sgaW5zZXJ0aW9uICovCgkgICAgYnJlYWs7CgoJY2FzZSAoYWN0aXZhdGVFdnQpOgoJICAgIGd1aV9tYWNfZG9BY3RpdmF0ZUV2ZW50KGV2ZW50KTsKCSAgICBicmVhazsKCgljYXNlIChvc0V2dCk6CgkgICAgc3dpdGNoICgoZXZlbnQtPm1lc3NhZ2UgPj4gMjQpICYgMHhGRikKCSAgICB7CgkJY2FzZSAoMHhGQSk6IC8qIG1vdXNlTW92ZWRNZXNzYWdlICovCgkJICAgIGd1aV9tYWNfZG9Nb3VzZU1vdmVkRXZlbnQoZXZlbnQpOwoJCSAgICBicmVhazsKCQljYXNlICgweDAxKTogLyogc3VzcGVuZFJlc3VtZU1lc3NhZ2UgKi8KCQkgICAgZ3VpX21hY19kb1N1c3BlbmRFdmVudChldmVudCk7CgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCiNpZmRlZiBVU0VfQUVWRU5UCgljYXNlIChrSGlnaExldmVsRXZlbnQpOgoJICAgIC8qIFNvbWVvbmUncyB0YWxraW5nIHRvIHVzLCB0aHJvdWdoIEFwcGxlRXZlbnRzICovCgkgICAgZXJyb3IgPSBBRVByb2Nlc3NBcHBsZUV2ZW50KGV2ZW50KTsgLyogVE9ETzogRXJyb3IgSGFuZGxpbmcgKi8KCSAgICBicmVhazsKI2VuZGlmCiAgICB9Cn0KCi8qCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBVbmtub3duIFN0dWZmCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCgogICAgR3VpRm9udApndWlfbWFjX2ZpbmRfZm9udChjaGFyX3UgKmZvbnRfbmFtZSkKewogICAgY2hhcl91CWM7CiAgICBjaGFyX3UJKnA7CiAgICBjaGFyX3UJcEZvbnROYW1lWzI1Nl07CiAgICBTdHIyNTUJc3lzdGVtRm9udG5hbWU7CiAgICBzaG9ydAlmb250X2lkOwogICAgc2hvcnQJc2l6ZT05OwogICAgR3VpRm9udAlmb250OwojaWYgMAogICAgY2hhcl91ICAgICAgKmZvbnROYW1lUHRyOwojZW5kaWYKCiAgICBmb3IgKHAgPSBmb250X25hbWU7ICgoKnAgIT0gMCkgJiYgKCpwICE9ICc6JykpOyBwKyspCgk7CgogICAgYyA9ICpwOwogICAgKnAgPSAwOwoKI2lmIDEKICAgIFNUUkNQWSgmcEZvbnROYW1lWzFdLCBmb250X25hbWUpOwogICAgcEZvbnROYW1lWzBdID0gU1RSTEVOKGZvbnRfbmFtZSk7CiAgICAqcCA9IGM7CgogICAgLyogR2V0IHRoZSBmb250IG5hbWUsIG1pbnVzIHRoZSBzdHlsZSBzdWZmaXggKDpoLCBldGMpICovCiAgICBjaGFyX3UgZm9udE5hbWVbMjU2XTsKICAgIGNoYXJfdSAqc3R5bGVTdGFydCA9IHZpbV9zdHJjaHIoZm9udF9uYW1lLCAnOicpOwogICAgc2l6ZV90IGZvbnROYW1lTGVuID0gc3R5bGVTdGFydCA/IHN0eWxlU3RhcnQgLSBmb250X25hbWUgOiBTVFJMRU4oZm9udE5hbWUpOwogICAgdmltX3N0cm5jcHkoZm9udE5hbWUsIGZvbnRfbmFtZSwgZm9udE5hbWVMZW4pOwoKICAgIEFUU1VGb250SUQgZm9udFJlZjsKICAgIEZNRm9udFN0eWxlIGZvbnRTdHlsZTsKICAgIGZvbnRfaWQgPSAwOwoKICAgIGlmIChBVFNVRmluZEZvbnRGcm9tTmFtZSgmcEZvbnROYW1lWzFdLCBwRm9udE5hbWVbMF0sIGtGb250RnVsbE5hbWUsCgkJa0ZvbnRNYWNpbnRvc2hQbGF0Zm9ybSwga0ZvbnROb1NjcmlwdENvZGUsIGtGb250Tm9MYW5ndWFnZUNvZGUsCgkJJmZvbnRSZWYpID09IG5vRXJyKQogICAgewoJaWYgKEZNR2V0Rm9udEZhbWlseUluc3RhbmNlRnJvbUZvbnQoZm9udFJlZiwgJmZvbnRfaWQsICZmb250U3R5bGUpICE9IG5vRXJyKQoJICAgIGZvbnRfaWQgPSAwOwogICAgfQoKICAgIGlmIChmb250X2lkID09IDApCiAgICB7CgkvKgoJICogVHJ5IGFnYWluLCB0aGlzIHRpbWUgcmVwbGFjaW5nIHVuZGVyc2NvcmVzIGluIHRoZSBmb250IG5hbWUKCSAqIHdpdGggc3BhY2VzICg6c2V0IGd1aWZvbnQgYWxsb3dzIHRoZSB0d28gdG8gYmUgdXNlZAoJICogaW50ZXJjaGFuZ2VhYmx5OyB0aGUgRm9udCBNYW5hZ2VyIGRvZXNuJ3QpLgoJICovCglpbnQgaSwgY2hhbmdlZCA9IEZBTFNFOwoKCWZvciAoaSA9IHBGb250TmFtZVswXTsgaSA+IDA7IC0taSkKCXsKCSAgICBpZiAocEZvbnROYW1lW2ldID09ICdfJykKCSAgICB7CgkJcEZvbnROYW1lW2ldID0gJyAnOwoJCWNoYW5nZWQgPSBUUlVFOwoJICAgIH0KCX0KCWlmIChjaGFuZ2VkKQoJICAgIGlmIChBVFNVRmluZEZvbnRGcm9tTmFtZSgmcEZvbnROYW1lWzFdLCBwRm9udE5hbWVbMF0sCgkJCWtGb250RnVsbE5hbWUsIGtGb250Tm9QbGF0Zm9ybUNvZGUsIGtGb250Tm9TY3JpcHRDb2RlLAoJCQlrRm9udE5vTGFuZ3VhZ2VDb2RlLCAmZm9udFJlZikgPT0gbm9FcnIpCgkgICAgewoJCWlmIChGTUdldEZvbnRGYW1pbHlJbnN0YW5jZUZyb21Gb250KGZvbnRSZWYsICZmb250X2lkLCAmZm9udFN0eWxlKSAhPSBub0VycikKCQkgICAgZm9udF9pZCA9IDA7CgkgICAgfQogICAgfQoKI2Vsc2UKICAgIC8qIG5hbWUgPSBDMlBhc2NhbF9zYXZlKG1lbnUtPmRuYW1lKTsgKi8KICAgIGZvbnROYW1lUHRyID0gQzJQYXNjYWxfc2F2ZV9hbmRfcmVtb3ZlX2JhY2tzbGFzaChmb250X25hbWUpOwoKICAgIEdldEZOdW0oZm9udE5hbWVQdHIsICZmb250X2lkKTsKI2VuZGlmCgoKICAgIGlmIChmb250X2lkID09IDApCiAgICB7CgkvKiBPdXBzLCB0aGUgc3lzdGVtIGZvbnQgd2FzIGl0IHRoZSBvbmUgdGhlIHVzZXIgd2FudCAqLwoKCWlmIChGTUdldEZvbnRGYW1pbHlOYW1lKHN5c3RlbUZvbnQsIHN5c3RlbUZvbnRuYW1lKSAhPSBub0VycikKCSAgICByZXR1cm4gTk9GT05UOwoJaWYgKCFFcXVhbFN0cmluZyhwRm9udE5hbWUsIHN5c3RlbUZvbnRuYW1lLCBmYWxzZSwgZmFsc2UpKQoJICAgIHJldHVybiBOT0ZPTlQ7CiAgICB9CiAgICBpZiAoKnAgPT0gJzonKQogICAgewoJcCsrOwoJLyogU2V0IHRoZSB2YWx1ZXMgZm91bmQgYWZ0ZXIgJzonICovCgl3aGlsZSAoKnApCgl7CgkgICAgc3dpdGNoICgqcCsrKQoJICAgIHsKCQljYXNlICdoJzoKCQkgICAgc2l6ZSA9IHBvaW50c190b19waXhlbHMocCwgJnAsIFRSVUUpOwoJCSAgICBicmVhazsKCQkgICAgLyoKCQkgICAgICogVE9ETzogTWF5YmUgYWNjZXB0IHdpZHRoIGFuZCBzdHlsZXMKCQkgICAgICovCgkgICAgfQoJICAgIHdoaWxlICgqcCA9PSAnOicpCgkJcCsrOwoJfQogICAgfQoKICAgIGlmIChzaXplIDwgMSkKCXNpemUgPSAxOyAgIC8qIEF2b2lkIGhhdmluZyBhIHNpemUgb2YgMCB3aXRoIHN5c3RlbSBmb250ICovCgogICAgZm9udCA9IChzaXplIDw8IDE2KSArICgobG9uZykgZm9udF9pZCAmIDB4RkZGRik7CgogICAgcmV0dXJuIGZvbnQ7Cn0KCi8qCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBHVUlfTUNIIGZ1bmN0aW9ubmFsaXR5CiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCi8qCiAqIFBhcnNlIHRoZSBHVUkgcmVsYXRlZCBjb21tYW5kLWxpbmUgYXJndW1lbnRzLiAgQW55IGFyZ3VtZW50cyB1c2VkIGFyZQogKiBkZWxldGVkIGZyb20gYXJndiwgYW5kICphcmdjIGlzIGRlY3JlbWVudGVkIGFjY29yZGluZ2x5LiAgVGhpcyBpcyBjYWxsZWQKICogd2hlbiB2aW0gaXMgc3RhcnRlZCwgd2hldGhlciBvciBub3QgdGhlIEdVSSBoYXMgYmVlbiBzdGFydGVkLgogKi8KICAgIHZvaWQKZ3VpX21jaF9wcmVwYXJlKGludCAqYXJnYywgY2hhciAqKmFyZ3YpCnsKICAgIC8qIFRPRE86IE1vdmUgbW9zdCBvZiB0aGlzIHN0dWZmIHRvd2FyZCBndWlfbWNoX2luaXQgKi8KI2lmZGVmIFVTRV9FWEVfTkFNRQogICAgRlNTcGVjCWFwcGxEaXI7CiMgaWZuZGVmIFVTRV9GSU5EX0JVTkRMRV9QQVRICiAgICBzaG9ydAlhcHBsVlJlZk51bTsKICAgIGxvbmcJYXBwbERpcklEOwogICAgU3RyMjU1CXZvbE5hbWU7CiMgZWxzZQogICAgUHJvY2Vzc1NlcmlhbE51bWJlciBwc247CiAgICBGU1JlZglhcHBsRlNSZWY7CiMgZW5kaWYKI2VuZGlmCgogICAgLyogV2h5IGRpZCBJIHB1dCB0aGF0IGluPyAoRGFueSkgKi8KICAgIE1vcmVNYXN0ZXJQb2ludGVycyAoMHg0MCAqIDMpOyAvKiB3ZSBsb3ZlIGhhbmRsZXMgKi8KCiNpZiAwCiAgICBJbml0Q3Vyc29yKCk7CgogICAgUmVnaXN0ZXJBcHBlYXJhbmNlQ2xpZW50KCk7CgojaWZkZWYgVVNFX0FFVkVOVAogICAgKHZvaWQpIEluc3RhbGxBRUhhbmRsZXJzKCk7CiNlbmRpZgoKICAgIGlmIChHZXN0YWx0KGdlc3RhbHRDb250ZXh0dWFsTWVudUF0dHIsICZnZXN0YWx0X3JjKSA9PSBub0VycikKCWd1aS5NYWNPU0hhdmVDbnR4TWVudSA9IEJpdFRzdCgmZ2VzdGFsdF9yYywgMzEtZ2VzdGFsdENvbnRleHR1YWxNZW51VHJhcEF2YWlsYWJsZSk7CiAgICBlbHNlCglndWkuTWFjT1NIYXZlQ250eE1lbnUgPSBmYWxzZTsKCiAgICBpZiAoZ3VpLk1hY09TSGF2ZUNudHhNZW51KQoJZ3VpLk1hY09TSGF2ZUNudHhNZW51ID0gKEluaXRDb250ZXh0dWFsTWVudXMoKT09bm9FcnIpOwoKICAgIHBvbW1lID0gTmV3TWVudSgyNTYsICJccFwwMjQiKTsgLyogMHgxND0gPSBBcHBsZSBNZW51ICovCgogICAgQXBwZW5kTWVudShwb21tZSwgIlxwQWJvdXQgVklNIik7CgogICAgSW5zZXJ0TWVudShwb21tZSwgMCk7CgogICAgRHJhd01lbnVCYXIoKTsKCgojaWZuZGVmIFVTRV9PRkZTRVRFRF9XSU5ET1cKICAgIFNldFJlY3QoJndpbmRSZWN0LCAxMCwgNDgsIDEwKzgwKjcgKyAxNiwgNDgrMjQqMTEpOwojZWxzZQogICAgU2V0UmVjdCgmd2luZFJlY3QsIDMwMCwgNDAsIDMwMCs4MCo3ICsgMTYsIDQwKzI0KjExKTsKI2VuZGlmCgoKICAgIENyZWF0ZU5ld1dpbmRvdyhrRG9jdW1lbnRXaW5kb3dDbGFzcywKCQlrV2luZG93UmVzaXphYmxlQXR0cmlidXRlIHwga1dpbmRvd0NvbGxhcHNlQm94QXR0cmlidXRlLAoJCSZ3aW5kUmVjdCwgJmd1aS5WaW1XaW5kb3cpOwogICAgU2V0UG9ydFdpbmRvd1BvcnQoZ3VpLlZpbVdpbmRvdyk7CgogICAgZ3VpLmNoYXJfd2lkdGggPSA3OwogICAgZ3VpLmNoYXJfaGVpZ2h0ID0gMTE7CiAgICBndWkuY2hhcl9hc2NlbnQgPSA2OwogICAgZ3VpLm51bV9yb3dzID0gMjQ7CiAgICBndWkubnVtX2NvbHMgPSA4MDsKICAgIGd1aS5pbl9mb2N1cyA9IFRSVUU7IC8qIEZvciB0aGUgbW9tZW50IC0+IHN5bi4gb2YgZnJvbnQgYXBwbGljYXRpb24gKi8KCiAgICBnU2Nyb2xsQWN0aW9uID0gTmV3Q29udHJvbEFjdGlvblVQUChndWlfbWFjX3Njcm9sbF9hY3Rpb24pOwogICAgZ1Njcm9sbERyYWcgICA9IE5ld0NvbnRyb2xBY3Rpb25VUFAoZ3VpX21hY19kcmFnX3RodW1iKTsKCiAgICBkcmFnUmVjdEVuYmwgPSBGQUxTRTsKICAgIGRyYWdSZ24gPSBOVUxMOwogICAgZHJhZ1JlY3RDb250cm9sID0ga0NyZWF0ZUVtcHR5OwogICAgY3Vyc29yUmduID0gTmV3UmduKCk7CiNlbmRpZgojaWZkZWYgVVNFX0VYRV9OQU1FCiMgaWZuZGVmIFVTRV9GSU5EX0JVTkRMRV9QQVRICiAgICBIR2V0Vm9sKHZvbE5hbWUsICZhcHBsVlJlZk51bSwgJmFwcGxEaXJJRCk7CiAgICAvKiBUTjIwMTU6IG1lbnRpb24gYSBwb3NzaWJsZSBiYWQgVlJlZk51bSAqLwogICAgRlNNYWtlRlNTcGVjKGFwcGxWUmVmTnVtLCBhcHBsRGlySUQsICJccCIsICZhcHBsRGlyKTsKIyBlbHNlCiAgICAvKiBPU0VyciBHZXRBcHBsaWNhdGlvbkJ1bmRsZUZTU3BlYyhGU1NwZWNQdHIgdGhlRlNTcGVjUHRyKQogICAgICogb2YgVE4yMDE1CiAgICAgKiBUaGlzIHRlY2huaWMgcmVtb3ZlIHRoZSAuLi9Db250ZW50cy9NYWNPUy9ldGMgcGFydAogICAgICovCiAgICAodm9pZClHZXRDdXJyZW50UHJvY2VzcygmcHNuKTsKICAgIC8qIGlmIChlcnIgIT0gbm9FcnIpIHJldHVybiBlcnI7ICovCgogICAgKHZvaWQpR2V0UHJvY2Vzc0J1bmRsZUxvY2F0aW9uKCZwc24sICZhcHBsRlNSZWYpOwogICAgLyogaWYgKGVyciAhPSBub0VycikgcmV0dXJuIGVycjsgKi8KCiAgICAodm9pZClGU0dldENhdGFsb2dJbmZvKCZhcHBsRlNSZWYsIGtGU0NhdEluZm9Ob25lLCBOVUxMLCBOVUxMLCAmYXBwbERpciwgTlVMTCk7CgogICAgLyogVGhpcyB0ZWNobmljIHJldHVybiBOSUwgd2hlbiB3ZSBkaXNhbGxvd19ndWkgKi8KIyBlbmRpZgogICAgZXhlX25hbWUgPSBGdWxsUGF0aEZyb21GU1NwZWNfc2F2ZShhcHBsRGlyKTsKI2VuZGlmCn0KCiNpZm5kZWYgQUxXQVlTX1VTRV9HVUkKLyoKICogQ2hlY2sgaWYgdGhlIEdVSSBjYW4gYmUgc3RhcnRlZC4gIENhbGxlZCBiZWZvcmUgZ3ZpbXJjIGlzIHNvdXJjZWQuCiAqIFJldHVybiBPSyBvciBGQUlMLgogKi8KICAgIGludApndWlfbWNoX2luaXRfY2hlY2sodm9pZCkKewogICAgLyogVE9ETzogRm9yIE1hY09TIFggZmluZCBhIHdheSB0byByZXR1cm4gRkFJTCwgaWYgdGhlIHVzZXIgbG9nZ2VkIGluCiAgICAgKiB1c2luZyB0aGUgPmNvbnNvbGUKICAgICAqLwogICAgaWYgKGRpc2FsbG93X2d1aSkgLyogc2VlIG1haW4uYyBmb3IgcmVhc29uIHRvIGRpc2FsbG93ICovCglyZXR1cm4gRkFJTDsKICAgIHJldHVybiBPSzsKfQojZW5kaWYKCiAgICBzdGF0aWMgT1NFcnIKcmVjZWl2ZUhhbmRsZXIoV2luZG93UmVmIHRoZVdpbmRvdywgdm9pZCogaGFuZGxlclJlZkNvbiwgRHJhZ1JlZiB0aGVEcmFnKQp7CiAgICBpbnQJCXgsIHk7CiAgICBpbnRfdQltb2RpZmllcnM7CiAgICBjaGFyX3UJKipmbmFtZXMgPSBOVUxMOwogICAgaW50CQljb3VudDsKICAgIGludAkJaSwgajsKCiAgICAvKiBHZXQgZHJvcCBwb3NpdGlvbiwgbW9kaWZpZXJzIGFuZCBjb3VudCBvZiBpdGVtcyAqLwogICAgewoJUG9pbnQJcG9pbnQ7CglTSW50MTYJbW91c2VVcE1vZGlmaWVyczsKCVVJbnQxNgljb3VudEl0ZW07CgoJR2V0RHJhZ01vdXNlKHRoZURyYWcsICZwb2ludCwgTlVMTCk7CglHbG9iYWxUb0xvY2FsKCZwb2ludCk7Cgl4ID0gcG9pbnQuaDsKCXkgPSBwb2ludC52OwoJR2V0RHJhZ01vZGlmaWVycyh0aGVEcmFnLCBOVUxMLCBOVUxMLCAmbW91c2VVcE1vZGlmaWVycyk7Cgltb2RpZmllcnMgPSBFdmVudE1vZGlmaWVyczJWaW1Nb3VzZU1vZGlmaWVycyhtb3VzZVVwTW9kaWZpZXJzKTsKCUNvdW50RHJhZ0l0ZW1zKHRoZURyYWcsICZjb3VudEl0ZW0pOwoJY291bnQgPSBjb3VudEl0ZW07CiAgICB9CgogICAgZm5hbWVzID0gKGNoYXJfdSAqKilhbGxvYyhjb3VudCAqIHNpemVvZihjaGFyX3UgKikpOwogICAgaWYgKGZuYW1lcyA9PSBOVUxMKQoJcmV0dXJuIGRyYWdOb3RBY2NlcHRlZEVycjsKCiAgICAvKiBHZXQgZmlsZSBuYW1lcyBkcm9wcGVkICovCiAgICBmb3IgKGkgPSBqID0gMDsgaSA8IGNvdW50OyArK2kpCiAgICB7CglEcmFnSXRlbVJlZglpdGVtOwoJT1NFcnIJCWVycjsKCVNpemUJCXNpemU7CglGbGF2b3JUeXBlCXR5cGUgPSBmbGF2b3JUeXBlSEZTOwoJSEZTRmxhdm9yCWhmc0ZsYXZvcjsKCglmbmFtZXNbaV0gPSBOVUxMOwoJR2V0RHJhZ0l0ZW1SZWZlcmVuY2VOdW1iZXIodGhlRHJhZywgaSArIDEsICZpdGVtKTsKCWVyciA9IEdldEZsYXZvckRhdGFTaXplKHRoZURyYWcsIGl0ZW0sIHR5cGUsICZzaXplKTsKCWlmIChlcnIgIT0gbm9FcnIgfHwgc2l6ZSA+IHNpemVvZihoZnNGbGF2b3IpKQoJICAgIGNvbnRpbnVlOwoJZXJyID0gR2V0Rmxhdm9yRGF0YSh0aGVEcmFnLCBpdGVtLCB0eXBlLCAmaGZzRmxhdm9yLCAmc2l6ZSwgMCk7CglpZiAoZXJyICE9IG5vRXJyKQoJICAgIGNvbnRpbnVlOwoJZm5hbWVzW2orK10gPSBGdWxsUGF0aEZyb21GU1NwZWNfc2F2ZShoZnNGbGF2b3IuZmlsZVNwZWMpOwogICAgfQogICAgY291bnQgPSBqOwoKICAgIGd1aV9oYW5kbGVfZHJvcCh4LCB5LCBtb2RpZmllcnMsIGZuYW1lcywgY291bnQpOwoKICAgIC8qIEZha2UgbW91c2UgZXZlbnQgdG8gd2FrZSBmcm9tIHN0YWxsICovCiAgICBQb3N0RXZlbnQobW91c2VVcCwgMCk7CgogICAgcmV0dXJuIG5vRXJyOwp9CgovKgogKiBJbml0aWFsaXNlIHRoZSBHVUkuICBDcmVhdGUgYWxsIHRoZSB3aW5kb3dzLCBzZXQgdXAgYWxsIHRoZSBjYWxsLWJhY2tzCiAqIGV0Yy4KICovCiAgICBpbnQKZ3VpX21jaF9pbml0KHZvaWQpCnsKICAgIC8qIFRPRE86IE1vdmUgbW9zdCBvZiB0aGlzIHN0dWZmIHRvd2FyZCBndWlfbWNoX2luaXQgKi8KICAgIFJlY3QJd2luZFJlY3Q7CiAgICBNZW51SGFuZGxlCXBvbW1lOwogICAgbG9uZwlnZXN0YWx0X3JjOwogICAgRXZlbnRUeXBlU3BlYyAgIGV2ZW50VHlwZVNwZWM7CiAgICBFdmVudEhhbmRsZXJSZWYgbW91c2VXaGVlbEhhbmRsZXJSZWY7CiNpZmRlZiBVU0VfQ0FSQk9OS0VZSEFORExFUgogICAgRXZlbnRIYW5kbGVyUmVmIGtleUV2ZW50SGFuZGxlclJlZjsKI2VuZGlmCgogICAgaWYgKEdlc3RhbHQoZ2VzdGFsdFN5c3RlbVZlcnNpb24sICZnTWFjU3lzdGVtVmVyc2lvbikgIT0gbm9FcnIpCglnTWFjU3lzdGVtVmVyc2lvbiA9IDB4MTAwMDsgLyogVE9ETzogRGVmYXVsdCB0byBtaW5pbXVtIHNlbnNpYmxlIHZhbHVlICovCgojaWYgMQogICAgSW5pdEN1cnNvcigpOwoKICAgIFJlZ2lzdGVyQXBwZWFyYW5jZUNsaWVudCgpOwoKI2lmZGVmIFVTRV9BRVZFTlQKICAgICh2b2lkKSBJbnN0YWxsQUVIYW5kbGVycygpOwojZW5kaWYKCiAgICAvKiBDdHJsIGNsaWNrICovCiAgICBpZiAoR2VzdGFsdChnZXN0YWx0Q29udGV4dHVhbE1lbnVBdHRyLCAmZ2VzdGFsdF9yYykgPT0gbm9FcnIpCglndWkuTWFjT1NIYXZlQ250eE1lbnUgPSBCaXRUc3QoJmdlc3RhbHRfcmMsIDMxLWdlc3RhbHRDb250ZXh0dWFsTWVudVRyYXBBdmFpbGFibGUpOwogICAgZWxzZQoJZ3VpLk1hY09TSGF2ZUNudHhNZW51ID0gZmFsc2U7CgogICAgaWYgKGd1aS5NYWNPU0hhdmVDbnR4TWVudSkKCWd1aS5NYWNPU0hhdmVDbnR4TWVudSA9IChJbml0Q29udGV4dHVhbE1lbnVzKCk9PW5vRXJyKTsKCiAgICBwb21tZSA9IE5ld01lbnUoMjU2LCAiXHBcMDI0Iik7IC8qIDB4MTQ9ID0gQXBwbGUgTWVudSAqLwoKICAgIEFwcGVuZE1lbnUocG9tbWUsICJccEFib3V0IFZJTSIpOwoKICAgIEluc2VydE1lbnUocG9tbWUsIDApOwoKICAgIERyYXdNZW51QmFyKCk7CgoKI2lmbmRlZiBVU0VfT0ZGU0VURURfV0lORE9XCiAgICBTZXRSZWN0KCZ3aW5kUmVjdCwgMTAsIDQ4LCAxMCs4MCo3ICsgMTYsIDQ4KzI0KjExKTsKI2Vsc2UKICAgIFNldFJlY3QoJndpbmRSZWN0LCAzMDAsIDQwLCAzMDArODAqNyArIDE2LCA0MCsyNCoxMSk7CiNlbmRpZgoKICAgIGd1aS5WaW1XaW5kb3cgPSBOZXdDV2luZG93KG5pbCwgJndpbmRSZWN0LCAiXHBnVmltIG9uIE1hY2ludG9zaCIsIHRydWUsCgkJCXpvb21Eb2NQcm9jLAoJCQkoV2luZG93UHRyKS0xTCwgdHJ1ZSwgMCk7CiAgICBJbnN0YWxsUmVjZWl2ZUhhbmRsZXIoKERyYWdSZWNlaXZlSGFuZGxlclVQUClyZWNlaXZlSGFuZGxlciwKCSAgICBndWkuVmltV2luZG93LCBOVUxMKTsKICAgIFNldFBvcnRXaW5kb3dQb3J0KGd1aS5WaW1XaW5kb3cpOwoKICAgIGd1aS5jaGFyX3dpZHRoID0gNzsKICAgIGd1aS5jaGFyX2hlaWdodCA9IDExOwogICAgZ3VpLmNoYXJfYXNjZW50ID0gNjsKICAgIGd1aS5udW1fcm93cyA9IDI0OwogICAgZ3VpLm51bV9jb2xzID0gODA7CiAgICBndWkuaW5fZm9jdXMgPSBUUlVFOyAvKiBGb3IgdGhlIG1vbWVudCAtPiBzeW4uIG9mIGZyb250IGFwcGxpY2F0aW9uICovCgogICAgZ1Njcm9sbEFjdGlvbiA9IE5ld0NvbnRyb2xBY3Rpb25VUFAoZ3VpX21hY19zY3JvbGxfYWN0aW9uKTsKICAgIGdTY3JvbGxEcmFnICAgPSBOZXdDb250cm9sQWN0aW9uVVBQKGd1aV9tYWNfZHJhZ190aHVtYik7CgogICAgLyogSW5zdGFsbCBDYXJib24gZXZlbnQgY2FsbGJhY2tzLiAqLwogICAgKHZvaWQpSW5zdGFsbEZvbnRQYW5lbEhhbmRsZXIoKTsKCiAgICBkcmFnUmVjdEVuYmwgPSBGQUxTRTsKICAgIGRyYWdSZ24gPSBOVUxMOwogICAgZHJhZ1JlY3RDb250cm9sID0ga0NyZWF0ZUVtcHR5OwogICAgY3Vyc29yUmduID0gTmV3UmduKCk7CiNlbmRpZgogICAgLyogRGlzcGxheSBhbnkgcGVuZGluZyBlcnJvciBtZXNzYWdlcyAqLwogICAgZGlzcGxheV9lcnJvcnMoKTsKCiAgICAvKiBHZXQgYmFja2dyb3VuZC9mb3JlZ3JvdW5kIGNvbG9ycyBmcm9tIHN5c3RlbSAqLwogICAgLyogVE9ETzogZG8gdGhlIGFwcHJvcmlhdGUgY2FsbCB0byBnZXQgcmVhbCBkZWZhdWx0cyAqLwogICAgZ3VpLm5vcm1fcGl4ZWwgPSAweDAwMDAwMDAwOwogICAgZ3VpLmJhY2tfcGl4ZWwgPSAweDAwRkZGRkZGOwoKICAgIC8qIEdldCB0aGUgY29sb3JzIGZyb20gdGhlICJOb3JtYWwiIGdyb3VwIChzZXQgaW4gc3ludGF4LmMgb3IgaW4gYSB2aW1yYwogICAgICogZmlsZSkuICovCiAgICBzZXRfbm9ybWFsX2NvbG9ycygpOwoKICAgIC8qCiAgICAgKiBDaGVjayB0aGF0IG5vbmUgb2YgdGhlIGNvbG9ycyBhcmUgdGhlIHNhbWUgYXMgdGhlIGJhY2tncm91bmQgY29sb3IuCiAgICAgKiBUaGVuIHN0b3JlIHRoZSBjdXJyZW50IHZhbHVlcyBhcyB0aGUgZGVmYXVsdHMuCiAgICAgKi8KICAgIGd1aV9jaGVja19jb2xvcnMoKTsKICAgIGd1aS5kZWZfbm9ybV9waXhlbCA9IGd1aS5ub3JtX3BpeGVsOwogICAgZ3VpLmRlZl9iYWNrX3BpeGVsID0gZ3VpLmJhY2tfcGl4ZWw7CgogICAgLyogR2V0IHRoZSBjb2xvcnMgZm9yIHRoZSBoaWdobGlnaHQgZ3JvdXBzIChndWlfY2hlY2tfY29sb3JzKCkgbWlnaHQgaGF2ZQogICAgICogY2hhbmdlZCB0aGVtKSAqLwogICAgaGlnaGxpZ2h0X2d1aV9zdGFydGVkKCk7CgogICAgLyoKICAgICAqIFNldHRpbmcgdGhlIGd1aSBjb25zdGFudHMKICAgICAqLwojaWZkZWYgRkVBVF9NRU5VCiAgICBndWkubWVudV9oZWlnaHQgPSAwOwojZW5kaWYKICAgIGd1aS5zY3JvbGxiYXJfaGVpZ2h0ID0gZ3VpLnNjcm9sbGJhcl93aWR0aCA9IDE1OyAvKiBjaGVhdCAxIG92ZXJsYXAgKi8KICAgIGd1aS5ib3JkZXJfb2Zmc2V0ID0gZ3VpLmJvcmRlcl93aWR0aCA9IDI7CgogICAgLyogSWYgUXVhcnR6LXN0eWxlIHRleHQgYW50aWFsaWFzaW5nIGlzIGF2YWlsYWJsZSAoc2VlCiAgICAgICBndWlfbWNoX2RyYXdfc3RyaW5nKCkgYmVsb3cpLCBlbmFibGUgaXQgZm9yIGFsbCBmb250IHNpemVzLiAqLwogICAgdmltX3NldGVudigoY2hhcl91ICopIlFEVEVYVF9NSU5TSVpFIiwgKGNoYXJfdSAqKSIxIik7CgogICAgZXZlbnRUeXBlU3BlYy5ldmVudENsYXNzID0ga0V2ZW50Q2xhc3NNb3VzZTsKICAgIGV2ZW50VHlwZVNwZWMuZXZlbnRLaW5kID0ga0V2ZW50TW91c2VXaGVlbE1vdmVkOwogICAgbW91c2VXaGVlbEhhbmRsZXJVUFAgPSBOZXdFdmVudEhhbmRsZXJVUFAoZ3VpX21hY19tb3VzZV93aGVlbCk7CiAgICBpZiAobm9FcnIgIT0gSW5zdGFsbEFwcGxpY2F0aW9uRXZlbnRIYW5kbGVyKG1vdXNlV2hlZWxIYW5kbGVyVVBQLCAxLAoJCQkJICZldmVudFR5cGVTcGVjLCBOVUxMLCAmbW91c2VXaGVlbEhhbmRsZXJSZWYpKQogICAgewoJbW91c2VXaGVlbEhhbmRsZXJSZWYgPSBOVUxMOwoJRGlzcG9zZUV2ZW50SGFuZGxlclVQUChtb3VzZVdoZWVsSGFuZGxlclVQUCk7Cgltb3VzZVdoZWVsSGFuZGxlclVQUCA9IE5VTEw7CiAgICB9CgojaWZkZWYgVVNFX0NBUkJPTktFWUhBTkRMRVIKICAgIGV2ZW50VHlwZVNwZWMuZXZlbnRDbGFzcyA9IGtFdmVudENsYXNzVGV4dElucHV0OwogICAgZXZlbnRUeXBlU3BlYy5ldmVudEtpbmQgPSBrRXZlbnRVbmljb2RlRm9yS2V5RXZlbnQ7CiAgICBrZXlFdmVudEhhbmRsZXJVUFAgPSBOZXdFdmVudEhhbmRsZXJVUFAoZ3VpX21hY19kb0tleUV2ZW50Q2FyYm9uKTsKICAgIGlmIChub0VyciAhPSBJbnN0YWxsQXBwbGljYXRpb25FdmVudEhhbmRsZXIoa2V5RXZlbnRIYW5kbGVyVVBQLCAxLAoJCSZldmVudFR5cGVTcGVjLCBOVUxMLCAma2V5RXZlbnRIYW5kbGVyUmVmKSkKICAgIHsKCWtleUV2ZW50SGFuZGxlclJlZiA9IE5VTEw7CglEaXNwb3NlRXZlbnRIYW5kbGVyVVBQKGtleUV2ZW50SGFuZGxlclVQUCk7CglrZXlFdmVudEhhbmRsZXJVUFAgPSBOVUxMOwogICAgfQojZW5kaWYKCi8qCiNpZmRlZiBGRUFUX01CWVRFCiAgICBzZXRfb3B0aW9uX3ZhbHVlKChjaGFyX3UgKikiZW5jb2RpbmciLCAwTCwgKGNoYXJfdSAqKSJ1dGYtOCIsIDApOwojZW5kaWYKKi8KCiAgICAvKiBUT0RPOiBMb2FkIGJpdG1hcCBpZiB1c2luZyBUT09MQkFSICovCiAgICByZXR1cm4gT0s7Cn0KCi8qCiAqIENhbGxlZCB3aGVuIHRoZSBmb3JlZ3JvdW5kIG9yIGJhY2tncm91bmQgY29sb3IgaGFzIGJlZW4gY2hhbmdlZC4KICovCiAgICB2b2lkCmd1aV9tY2hfbmV3X2NvbG9ycyh2b2lkKQp7CiAgICAvKiBUT0RPOgogICAgICogVGhpcyBwcm9jIGlzIGNhbGxlZCB3aGVuIE5vcm1hbCBpcyBzZXQgdG8gYSB2YWx1ZQogICAgICogc28gd2hhdCBtc3V0IGJlIGRvbmU/IEkgZG9uJ3Qga25vdwogICAgICovCn0KCi8qCiAqIE9wZW4gdGhlIEdVSSB3aW5kb3cgd2hpY2ggd2FzIGNyZWF0ZWQgYnkgYSBjYWxsIHRvIGd1aV9tY2hfaW5pdCgpLgogKi8KICAgIGludApndWlfbWNoX29wZW4odm9pZCkKewogICAgU2hvd1dpbmRvdyhndWkuVmltV2luZG93KTsKCiAgICBpZiAoZ3VpX3dpbl94ICE9IC0xICYmIGd1aV93aW5feSAhPSAtMSkKCWd1aV9tY2hfc2V0X3dpbnBvcyhndWlfd2luX3gsIGd1aV93aW5feSk7CgogICAgLyoKICAgICAqIE1ha2UgdGhlIEdVSSB0aGUgZm9yZWdyb3VuZCBwcm9jZXNzIChpbiBjYXNlIGl0IHdhcyBsYXVuY2hlZAogICAgICogZnJvbSB0aGUgVGVybWluYWwgb3IgdmlhIDpndWkpLgogICAgICovCiAgICB7CglQcm9jZXNzU2VyaWFsTnVtYmVyIHBzbjsKCWlmIChHZXRDdXJyZW50UHJvY2VzcygmcHNuKSA9PSBub0VycikKCSAgICBTZXRGcm9udFByb2Nlc3MoJnBzbik7CiAgICB9CgogICAgcmV0dXJuIE9LOwp9CgogICAgdm9pZApndWlfbWNoX2V4aXQoaW50IHJjKQp7CiAgICAvKiBUT0RPOiBmaW5kIG91dCBhbGwgd2hhdCBpcyBtaXNzaW5nIGhlcmU/ICovCiAgICBEaXNwb3NlUmduKGN1cnNvclJnbik7CgojaWZkZWYgVVNFX0NBUkJPTktFWUhBTkRMRVIKICAgIGlmIChrZXlFdmVudEhhbmRsZXJVUFApCglEaXNwb3NlRXZlbnRIYW5kbGVyVVBQKGtleUV2ZW50SGFuZGxlclVQUCk7CiNlbmRpZgoKICAgIGlmIChtb3VzZVdoZWVsSGFuZGxlclVQUCAhPSBOVUxMKQoJRGlzcG9zZUV2ZW50SGFuZGxlclVQUChtb3VzZVdoZWVsSGFuZGxlclVQUCk7CgojaWZkZWYgVVNFX0FUU1VJX0RSQVdJTkcKICAgIGlmIChwX21hY2F0c3VpICYmIGdGb250U3R5bGUpCglBVFNVRGlzcG9zZVN0eWxlKGdGb250U3R5bGUpOwojZW5kaWYKCiAgICAvKiBFeGl0IHRvIHNoZWxsPyAqLwogICAgZXhpdChyYyk7Cn0KCi8qCiAqIEdldCB0aGUgcG9zaXRpb24gb2YgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgd2luZG93LgogKi8KICAgIGludApndWlfbWNoX2dldF93aW5wb3MoaW50ICp4LCBpbnQgKnkpCnsKICAgIC8qIFRPRE8gKi8KICAgIFJlY3QJYm91bmRzOwogICAgT1NTdGF0dXMJc3RhdHVzOwoKICAgIC8qIENhcmJvbiA+PSAxLjAuMiwgTWFjT1MgPj0gOC41ICovCiAgICBzdGF0dXMgPSBHZXRXaW5kb3dCb3VuZHMoZ3VpLlZpbVdpbmRvdywga1dpbmRvd1N0cnVjdHVyZVJnbiwgJmJvdW5kcyk7CgogICAgaWYgKHN0YXR1cyAhPSBub0VycikKCXJldHVybiBGQUlMOwogICAgKnggPSBib3VuZHMubGVmdDsKICAgICp5ID0gYm91bmRzLnRvcDsKICAgIHJldHVybiBPSzsKICAgIHJldHVybiBGQUlMOwp9CgovKgogKiBTZXQgdGhlIHBvc2l0aW9uIG9mIHRoZSB0b3AgbGVmdCBjb3JuZXIgb2YgdGhlIHdpbmRvdyB0byB0aGUgZ2l2ZW4KICogY29vcmRpbmF0ZXMuCiAqLwogICAgdm9pZApndWlfbWNoX3NldF93aW5wb3MoaW50IHgsIGludCB5KQp7CiAgICAvKiBUT0RPOiAgU2hvdWxkIG1ha2Ugc3VyZSB0aGUgd2luZG93IGlzIG1vdmUgd2l0aGluIHJhbmdlCiAgICAgKgkgICAgICBlLmcuOiB5ID4gfjE2IFtNZW51IGJhcl0sIHggPiAwLCB4IDwgc2NyZWVuIHdpZHRoCiAgICAgKi8KICAgIE1vdmVXaW5kb3coZ3VpLlZpbVdpbmRvdywgeCwgeSwgVFJVRSk7Cn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0X3NoZWxsc2l6ZSgKICAgIGludAkJd2lkdGgsCiAgICBpbnQJCWhlaWdodCwKICAgIGludAkJbWluX3dpZHRoLAogICAgaW50CQltaW5faGVpZ2h0LAogICAgaW50CQliYXNlX3dpZHRoLAogICAgaW50CQliYXNlX2hlaWdodCwKICAgIGludAkJZGlyZWN0aW9uKQp7CiAgICBDR3JhZlB0cglWaW1Qb3J0OwogICAgUmVjdAlWaW1Cb3VuZDsKCiAgICBpZiAoZ3VpLndoaWNoX3Njcm9sbGJhcnNbU0JBUl9MRUZUXSkKICAgIHsKCVZpbVBvcnQgPSBHZXRXaW5kb3dQb3J0KGd1aS5WaW1XaW5kb3cpOwoJR2V0UG9ydEJvdW5kcyhWaW1Qb3J0LCAmVmltQm91bmQpOwoJVmltQm91bmQubGVmdCA9IC1ndWkuc2Nyb2xsYmFyX3dpZHRoOyAvKiArIDE7Ki8KCVNldFBvcnRCb3VuZHMoVmltUG9ydCwgJlZpbUJvdW5kKTsKICAgIC8qCUdldFdpbmRvd0JvdW5kcyhndWkuVmltV2luZG93LCBrV2luZG93R2xvYmFsUG9ydFJnbiwgJndpblBvcnRSZWN0KTsgPz8qLwogICAgfQogICAgZWxzZQogICAgewoJVmltUG9ydCA9IEdldFdpbmRvd1BvcnQoZ3VpLlZpbVdpbmRvdyk7CglHZXRQb3J0Qm91bmRzKFZpbVBvcnQsICZWaW1Cb3VuZCk7CglWaW1Cb3VuZC5sZWZ0ID0gMDsKCVNldFBvcnRCb3VuZHMoVmltUG9ydCwgJlZpbUJvdW5kKTsKICAgIH0KCiAgICBTaXplV2luZG93KGd1aS5WaW1XaW5kb3csIHdpZHRoLCBoZWlnaHQsIFRSVUUpOwoKICAgIGd1aV9yZXNpemVfc2hlbGwod2lkdGgsIGhlaWdodCk7Cn0KCi8qCiAqIEdldCB0aGUgc2NyZWVuIGRpbWVuc2lvbnMuCiAqIEFsbG93IDEwIHBpeGVscyBmb3IgaG9yaXpvbnRhbCBib3JkZXJzLCA0MCBmb3IgdmVydGljYWwgYm9yZGVycy4KICogSXMgdGhlcmUgbm8gd2F5IHRvIGZpbmQgb3V0IGhvdyB3aWRlIHRoZSBib3JkZXJzIHJlYWxseSBhcmU/CiAqIFRPRE86IEFkZCBsaXZlIHVkYXRlIG9mIHRob3NlIHZhbHVlIG9uIHN1c3BlbmQvcmVzdW1lLgogKi8KICAgIHZvaWQKZ3VpX21jaF9nZXRfc2NyZWVuX2RpbWVuc2lvbnMoaW50ICpzY3JlZW5fdywgaW50ICpzY3JlZW5faCkKewogICAgR0RIYW5kbGUJZG9taW5hbnREZXZpY2UgPSBHZXRNYWluRGV2aWNlKCk7CiAgICBSZWN0CXNjcmVlblJlY3QgPSAoKipkb21pbmFudERldmljZSkuZ2RSZWN0OwoKICAgICpzY3JlZW5fdyA9IHNjcmVlblJlY3QucmlnaHQgLSAxMDsKICAgICpzY3JlZW5faCA9IHNjcmVlblJlY3QuYm90dG9tIC0gNDA7Cn0KCgovKgogKiBPcGVuIHRoZSBGb250IFBhbmVsIGFuZCB3YWl0IGZvciB0aGUgdXNlciB0byBzZWxlY3QgYSBmb250IGFuZAogKiBjbG9zZSB0aGUgcGFuZWwuICBUaGVuIGZpbGwgdGhlIGJ1ZmZlciBwb2ludGVkIHRvIGJ5IGZvbnRfbmFtZSB3aXRoCiAqIHRoZSBuYW1lIGFuZCBzaXplIG9mIHRoZSBzZWxlY3RlZCBmb250IGFuZCByZXR1cm4gdGhlIGZvbnQncyBoYW5kbGUsCiAqIG9yIE5PRk9OVCBpbiBjYXNlIG9mIGFuIGVycm9yLgogKi8KICAgIHN0YXRpYyBHdWlGb250Cmd1aV9tYWNfc2VsZWN0X2ZvbnQoY2hhcl91ICpmb250X25hbWUpCnsKICAgIEd1aUZvbnQJCSAgICBzZWxlY3RlZF9mb250ID0gTk9GT05UOwogICAgT1NTdGF0dXMJCSAgICBzdGF0dXM7CiAgICBGb250U2VsZWN0aW9uUURTdHlsZSAgICBjdXJyX2ZvbnQ7CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgRm9udCBQYW5lbCB3aXRoIHRoZSBjdXJyZW50IGZvbnQuICovCiAgICBjdXJyX2ZvbnQuaW5zdGFuY2UuZm9udEZhbWlseSA9IGd1aS5ub3JtX2ZvbnQgJiAweEZGRkY7CiAgICBjdXJyX2ZvbnQuc2l6ZSA9IChndWkubm9ybV9mb250ID4+IDE2KTsKICAgIC8qIFRPRE86IHNldCBmb250U3R5bGUgb25jZSBzdHlsZXMgYXJlIHN1cHBvcnRlZCBpbiBndWlfbWFjX2ZpbmRfZm9udCgpICovCiAgICBjdXJyX2ZvbnQuaW5zdGFuY2UuZm9udFN0eWxlID0gMDsKICAgIGN1cnJfZm9udC5oYXNDb2xvciA9IGZhbHNlOwogICAgY3Vycl9mb250LnZlcnNpb24gPSAwOyAvKiB2ZXJzaW9uIG51bWJlciBvZiB0aGUgc3R5bGUgc3RydWN0dXJlICovCiAgICBzdGF0dXMgPSBTZXRGb250SW5mb0ZvclNlbGVjdGlvbihrRm9udFNlbGVjdGlvblFEVHlwZSwKCSAgICAvKm51bVN0eWxlcz0qLzEsICZjdXJyX2ZvbnQsIC8qZXZlbnRUYXJnZXQ9Ki9OVUxMKTsKCiAgICBnRm9udFBhbmVsSW5mby5mYW1pbHkgPSBjdXJyX2ZvbnQuaW5zdGFuY2UuZm9udEZhbWlseTsKICAgIGdGb250UGFuZWxJbmZvLnN0eWxlID0gY3Vycl9mb250Lmluc3RhbmNlLmZvbnRTdHlsZTsKICAgIGdGb250UGFuZWxJbmZvLnNpemUgPSBjdXJyX2ZvbnQuc2l6ZTsKCiAgICAvKiBQb3AgdXAgdGhlIEZvbnQgUGFuZWwuICovCiAgICBzdGF0dXMgPSBGUFNob3dIaWRlRm9udFBhbmVsKCk7CiAgICBpZiAoc3RhdHVzID09IG5vRXJyKQogICAgewoJLyoKCSAqIFRoZSBGb250IFBhbmVsIGlzIG1vZGVsZXNzLiAgV2UgcmVhbGx5IG5lZWQgaXQgdG8gYmUgbW9kYWwsCgkgKiBzbyB3ZSBzcGluIGluIGFuIGV2ZW50IGxvb3AgdW50aWwgdGhlIHBhbmVsIGlzIGNsb3NlZC4KCSAqLwoJZ0ZvbnRQYW5lbEluZm8uaXNQYW5lbFZpc2libGUgPSB0cnVlOwoJd2hpbGUgKGdGb250UGFuZWxJbmZvLmlzUGFuZWxWaXNpYmxlKQoJewoJICAgIEV2ZW50UmVjb3JkIGU7CgkgICAgV2FpdE5leHRFdmVudChldmVyeUV2ZW50LCAmZSwgLypzbGVlcD0qLzIwLCAvKm1vdXNlUmduPSovTlVMTCk7Cgl9CgoJR2V0Rm9udFBhbmVsU2VsZWN0aW9uKGZvbnRfbmFtZSk7CglzZWxlY3RlZF9mb250ID0gZ3VpX21hY19maW5kX2ZvbnQoZm9udF9uYW1lKTsKICAgIH0KICAgIHJldHVybiBzZWxlY3RlZF9mb250Owp9CgoKLyoKICogSW5pdGlhbGlzZSB2aW0gdG8gdXNlIHRoZSBmb250IHdpdGggdGhlIGdpdmVuIG5hbWUuCVJldHVybiBGQUlMIGlmIHRoZSBmb250CiAqIGNvdWxkIG5vdCBiZSBsb2FkZWQsIE9LIG90aGVyd2lzZS4KICovCiAgICBpbnQKZ3VpX21jaF9pbml0X2ZvbnQoY2hhcl91ICpmb250X25hbWUsIGludCBmb250c2V0KQp7CiAgICAvKiBUT0RPOiBBZGQgc3VwcG9ydCBmb3IgYm9sZCBpdGFsaWMgdW5kZXJsaW5lIHByb3BvcnRpb25hbCBldGMuLi4gKi8KICAgIFN0cjI1NQlzdWdnZXN0ZWRGb250ID0gIlxwTW9uYWNvIjsKICAgIGludAkJc3VnZ2VzdGVkU2l6ZSA9IDEwOwogICAgRm9udEluZm8JZm9udF9pbmZvOwogICAgc2hvcnQJZm9udF9pZDsKICAgIEd1aUZvbnQJZm9udDsKICAgIGNoYXJfdQl1c2VkX2ZvbnRfbmFtZVs1MTJdOwoKI2lmZGVmIFVTRV9BVFNVSV9EUkFXSU5HCiAgICBpZiAocF9tYWNhdHN1aSAmJiBnRm9udFN0eWxlID09IE5VTEwpCiAgICB7CglpZiAoQVRTVUNyZWF0ZVN0eWxlKCZnRm9udFN0eWxlKSAhPSBub0VycikKCSAgICBnRm9udFN0eWxlID0gTlVMTDsKICAgIH0KI2VuZGlmCgogICAgaWYgKGZvbnRfbmFtZSA9PSBOVUxMKQogICAgewoJLyogRmlyc3QgdHJ5IHRvIGdldCB0aGUgc3VnZ2VzdGVkIGZvbnQgKi8KCUdldEZOdW0oc3VnZ2VzdGVkRm9udCwgJmZvbnRfaWQpOwoKCWlmIChmb250X2lkID09IDApCgl7CgkgICAgLyogVGhlbiBwaWNrdXAgdGhlIHN0YW5kYXJkIGFwcGxpY2F0aW9uIGZvbnQgKi8KCSAgICBmb250X2lkID0gR2V0QXBwRm9udCgpOwoJICAgIFNUUkNQWSh1c2VkX2ZvbnRfbmFtZSwgImRlZmF1bHQiKTsKCX0KCWVsc2UKCSAgICBTVFJDUFkodXNlZF9mb250X25hbWUsICJNb25hY28iKTsKCWZvbnQgPSAoc3VnZ2VzdGVkU2l6ZSA8PCAxNikgKyAoKGxvbmcpIGZvbnRfaWQgJiAweEZGRkYpOwogICAgfQogICAgZWxzZSBpZiAoU1RSQ01QKGZvbnRfbmFtZSwgIioiKSA9PSAwKQogICAgewoJY2hhcl91ICpuZXdfcF9ndWlmb250OwoKCWZvbnQgPSBndWlfbWFjX3NlbGVjdF9mb250KHVzZWRfZm9udF9uYW1lKTsKCWlmIChmb250ID09IE5PRk9OVCkKCSAgICByZXR1cm4gRkFJTDsKCgkvKiBTZXQgZ3VpZm9udCB0byB0aGUgbmFtZSBvZiB0aGUgc2VsZWN0ZWQgZm9udC4gKi8KCW5ld19wX2d1aWZvbnQgPSBhbGxvYyhTVFJMRU4odXNlZF9mb250X25hbWUpICsgMSk7CglpZiAobmV3X3BfZ3VpZm9udCAhPSBOVUxMKQoJewoJICAgIFNUUkNQWShuZXdfcF9ndWlmb250LCB1c2VkX2ZvbnRfbmFtZSk7CgkgICAgdmltX2ZyZWUocF9ndWlmb250KTsKCSAgICBwX2d1aWZvbnQgPSBuZXdfcF9ndWlmb250OwoJICAgIC8qIFJlcGxhY2Ugc3BhY2VzIGluIHRoZSBmb250IG5hbWUgd2l0aCB1bmRlcnNjb3Jlcy4gKi8KCSAgICBmb3IgKCA7ICpuZXdfcF9ndWlmb250OyArK25ld19wX2d1aWZvbnQpCgkgICAgewoJCWlmICgqbmV3X3BfZ3VpZm9udCA9PSAnICcpCgkJICAgICpuZXdfcF9ndWlmb250ID0gJ18nOwoJICAgIH0KCX0KICAgIH0KICAgIGVsc2UKICAgIHsKCWZvbnQgPSBndWlfbWFjX2ZpbmRfZm9udChmb250X25hbWUpOwoJdmltX3N0cm5jcHkodXNlZF9mb250X25hbWUsIGZvbnRfbmFtZSwgc2l6ZW9mKHVzZWRfZm9udF9uYW1lKSAtIDEpOwoKCWlmIChmb250ID09IE5PRk9OVCkKCSAgICByZXR1cm4gRkFJTDsKICAgIH0KCiAgICBndWkubm9ybV9mb250ID0gZm9udDsKCiAgICBobF9zZXRfZm9udF9uYW1lKHVzZWRfZm9udF9uYW1lKTsKCiAgICBUZXh0U2l6ZShmb250ID4+IDE2KTsKICAgIFRleHRGb250KGZvbnQgJiAweEZGRkYpOwoKICAgIEdldEZvbnRJbmZvKCZmb250X2luZm8pOwoKICAgIGd1aS5jaGFyX2FzY2VudCA9IGZvbnRfaW5mby5hc2NlbnQ7CiAgICBndWkuY2hhcl93aWR0aCAgPSBDaGFyV2lkdGgoJ18nKTsKICAgIGd1aS5jaGFyX2hlaWdodCA9IGZvbnRfaW5mby5hc2NlbnQgKyBmb250X2luZm8uZGVzY2VudCArIHBfbGluZXNwYWNlOwoKI2lmZGVmIFVTRV9BVFNVSV9EUkFXSU5HCiAgICBBVFNVRm9udElECQkJZm9udElEOwogICAgRml4ZWQJCQlmb250U2l6ZTsKICAgIEFUU1N0eWxlUmVuZGVyaW5nT3B0aW9ucwlmb250T3B0aW9uczsKCiAgICBpZiAocF9tYWNhdHN1aSAmJiBnRm9udFN0eWxlKQogICAgewoJZm9udElEID0gZm9udCAmIDB4RkZGRjsKCWZvbnRTaXplID0gTG9uZzJGaXgoZm9udCA+PiAxNik7CgoJLyogTm8gYW50aWFsaWFzaW5nIGJ5IGRlZmF1bHQgKGRvIG5vdCBhdHRlbXB0IHRvIHRvdWNoIGFudGlhbGlzaW5nCgkgKiBvcHRpb25zIG9uIHByZS1KYWd1YXIpICovCglmb250T3B0aW9ucyA9CgkgICAgKGdNYWNTeXN0ZW1WZXJzaW9uID49IDB4MTAyMCkgPwoJICAgIGtBVFNTdHlsZU5vQW50aUFsaWFzaW5nIDoKCSAgICBrQVRTU3R5bGVOb09wdGlvbnM7CgoJQVRTVUF0dHJpYnV0ZVRhZyBhdHRyaWJUYWdzW10gPQoJewoJICAgIGtBVFNVRm9udFRhZywga0FUU1VTaXplVGFnLCBrQVRTVVN0eWxlUmVuZGVyaW5nT3B0aW9uc1RhZywKCSAgICBrQVRTVU1heEFUU1VJVGFnVmFsdWUrMQoJfTsKCUJ5dGVDb3VudCBhdHRyaWJTaXplc1tdID0KCXsKCSAgICBzaXplb2YoQVRTVUZvbnRJRCksIHNpemVvZihGaXhlZCksCgkgICAgc2l6ZW9mKEFUU1N0eWxlUmVuZGVyaW5nT3B0aW9ucyksIHNpemVvZiBmb250Cgl9OwoJQVRTVUF0dHJpYnV0ZVZhbHVlUHRyIGF0dHJpYlZhbHVlc1tdID0KCXsKCSAgICAmZm9udElELCAmZm9udFNpemUsICZmb250T3B0aW9ucywgJmZvbnQKCX07CgoJLyogQ29udmVydCBmb250IGlkIHRvIEFUU1VGb250SUQgKi8KCWlmIChGTUdldEZvbnRGcm9tRm9udEZhbWlseUluc3RhbmNlKGZvbnRJRCwgMCwgJmZvbnRJRCwgTlVMTCkgPT0gbm9FcnIpCgl7CgkgICAgaWYgKEFUU1VTZXRBdHRyaWJ1dGVzKGdGb250U3R5bGUsCgkJCShzaXplb2YgYXR0cmliVGFncykvc2l6ZW9mKEFUU1VBdHRyaWJ1dGVUYWcpLAoJCQlhdHRyaWJUYWdzLCBhdHRyaWJTaXplcywgYXR0cmliVmFsdWVzKSAhPSBub0VycikKCSAgICB7CgkJQVRTVURpc3Bvc2VTdHlsZShnRm9udFN0eWxlKTsKCQlnRm9udFN0eWxlID0gTlVMTDsKCSAgICB9Cgl9CiAgICB9CiNlbmRpZgoKICAgIHJldHVybiBPSzsKfQoKLyoKICogQWRqdXN0IGd1aS5jaGFyX2hlaWdodCAoYWZ0ZXIgJ2xpbmVzcGFjZScgd2FzIGNoYW5nZWQpLgogKi8KICAgIGludApndWlfbWNoX2FkanVzdF9jaGFyaGVpZ2h0KHZvaWQpCnsKICAgIEZvbnRJbmZvICAgIGZvbnRfaW5mbzsKCiAgICBHZXRGb250SW5mbygmZm9udF9pbmZvKTsKICAgIGd1aS5jaGFyX2hlaWdodCA9IGZvbnRfaW5mby5hc2NlbnQgKyBmb250X2luZm8uZGVzY2VudCArIHBfbGluZXNwYWNlOwogICAgZ3VpLmNoYXJfYXNjZW50ID0gZm9udF9pbmZvLmFzY2VudCArIHBfbGluZXNwYWNlIC8gMjsKICAgIHJldHVybiBPSzsKfQoKLyoKICogR2V0IGEgZm9udCBzdHJ1Y3R1cmUgZm9yIGhpZ2hsaWdodGluZy4KICovCiAgICBHdWlGb250Cmd1aV9tY2hfZ2V0X2ZvbnQoY2hhcl91ICpuYW1lLCBpbnQgZ2l2ZUVycm9ySWZNaXNzaW5nKQp7CiAgICBHdWlGb250IGZvbnQ7CgogICAgZm9udCA9IGd1aV9tYWNfZmluZF9mb250KG5hbWUpOwoKICAgIGlmIChmb250ID09IE5PRk9OVCkKICAgIHsKCWlmIChnaXZlRXJyb3JJZk1pc3NpbmcpCgkgICAgRU1TRzIoXyhlX2ZvbnQpLCBuYW1lKTsKCXJldHVybiBOT0ZPTlQ7CiAgICB9CiAgICAvKgogICAgICogVE9ETyA6IEFjY2VwdCBvbmx5IG1vbm9zcGFjZQogICAgICovCgogICAgcmV0dXJuIGZvbnQ7Cn0KCiNpZiBkZWZpbmVkKEZFQVRfRVZBTCkgfHwgZGVmaW5lZChQUk9UTykKLyoKICogUmV0dXJuIHRoZSBuYW1lIG9mIGZvbnQgImZvbnQiIGluIGFsbG9jYXRlZCBtZW1vcnkuCiAqIERvbid0IGtub3cgaG93IHRvIGdldCB0aGUgYWN0dWFsIG5hbWUsIHRodXMgdXNlIHRoZSBwcm92aWRlZCBuYW1lLgogKi8KICAgIGNoYXJfdSAqCmd1aV9tY2hfZ2V0X2ZvbnRuYW1lKEd1aUZvbnQgZm9udCwgY2hhcl91ICpuYW1lKQp7CiAgICBpZiAobmFtZSA9PSBOVUxMKQoJcmV0dXJuIE5VTEw7CiAgICByZXR1cm4gdmltX3N0cnNhdmUobmFtZSk7Cn0KI2VuZGlmCgovKgogKiBTZXQgdGhlIGN1cnJlbnQgdGV4dCBmb250LgogKi8KICAgIHZvaWQKZ3VpX21jaF9zZXRfZm9udChHdWlGb250IGZvbnQpCnsKI2lmZGVmIFVTRV9BVFNVSV9EUkFXSU5HCiAgICBHdWlGb250CQkJY3VyckZvbnQ7CiAgICBCeXRlQ291bnQJCQlhY3R1YWxGb250Qnl0ZUNvdW50OwogICAgQVRTVUZvbnRJRAkJCWZvbnRJRDsKICAgIEZpeGVkCQkJZm9udFNpemU7CiAgICBBVFNTdHlsZVJlbmRlcmluZ09wdGlvbnMJZm9udE9wdGlvbnM7CgogICAgaWYgKHBfbWFjYXRzdWkgJiYgZ0ZvbnRTdHlsZSkKICAgIHsKCS8qIEF2b2lkIHNldHRpbmcgc2FtZSBmb250IGFnYWluICovCglpZiAoQVRTVUdldEF0dHJpYnV0ZShnRm9udFN0eWxlLCBrQVRTVU1heEFUU1VJVGFnVmFsdWUrMSwgc2l6ZW9mIGZvbnQsCgkJICAgICZjdXJyRm9udCwgJmFjdHVhbEZvbnRCeXRlQ291bnQpID09IG5vRXJyICYmCgkJYWN0dWFsRm9udEJ5dGVDb3VudCA9PSAoc2l6ZW9mIGZvbnQpKQoJewoJICAgIGlmIChjdXJyRm9udCA9PSBmb250KQoJCXJldHVybjsKCX0KCglmb250SUQgPSBmb250ICYgMHhGRkZGOwoJZm9udFNpemUgPSBMb25nMkZpeChmb250ID4+IDE2KTsKCS8qIFJlc3BlY3QgcF9hbnRpYWxpYXMgc2V0dGluZyBvbmx5IGZvciB3aWRlIGZvbnQuCgkgKiBUaGUgcmVhc29uIGZvciBkb2luZyB0aGlzIGF0IHRoZSBtb21lbnQgaXMgYSBiaXQgY29tcGxpY2F0ZWQsCgkgKiBidXQgaXQncyBtYWlubHkgYmVjYXVzZSBhKSBsYXRpbiAobm9uLXdpZGUpIGFsaWFzZWQgZm9udHMKCSAqIGxvb2sgYmFkIGluIE9TIFggMTAuMy54IGFuZCBiZWxvdyAoZHVlIHRvIGEgYnVnIGluIEFUUyksIGFuZAoJICogYikgd2lkZSBtdWx0aWJ5dGUgaW5wdXQgZG9lcyBub3Qgc3VmZmVyIGZyb20gdGhhdCBwcm9ibGVtLiAqLwoJLypmb250T3B0aW9ucyA9CgkgICAgKHBfYW50aWFsaWFzICYmIChmb250ID09IGd1aS53aWRlX2ZvbnQpKSA/CgkgICAga0FUU1N0eWxlTm9PcHRpb25zIDoga0FUU1N0eWxlTm9BbnRpQWxpYXNpbmc7CgkqLwoJLypmb250T3B0aW9ucyA9IGtBVFNTdHlsZUFudGlBbGlhc2luZzsqLwoKCUFUU1VBdHRyaWJ1dGVUYWcgYXR0cmliVGFnc1tdID0KCXsKCSAgICBrQVRTVUZvbnRUYWcsIGtBVFNVU2l6ZVRhZywga0FUU1VTdHlsZVJlbmRlcmluZ09wdGlvbnNUYWcsCgkgICAga0FUU1VNYXhBVFNVSVRhZ1ZhbHVlKzEKCX07CglCeXRlQ291bnQgYXR0cmliU2l6ZXNbXSA9Cgl7CgkgICAgc2l6ZW9mKEFUU1VGb250SUQpLCBzaXplb2YoRml4ZWQpLAoJICAgIHNpemVvZihBVFNTdHlsZVJlbmRlcmluZ09wdGlvbnMpLCBzaXplb2YgZm9udAoJfTsKCUFUU1VBdHRyaWJ1dGVWYWx1ZVB0ciBhdHRyaWJWYWx1ZXNbXSA9Cgl7CgkgICAgJmZvbnRJRCwgJmZvbnRTaXplLCAmZm9udE9wdGlvbnMsICZmb250Cgl9OwoKCWlmIChGTUdldEZvbnRGcm9tRm9udEZhbWlseUluc3RhbmNlKGZvbnRJRCwgMCwgJmZvbnRJRCwgTlVMTCkgPT0gbm9FcnIpCgl7CgkgICAgaWYgKEFUU1VTZXRBdHRyaWJ1dGVzKGdGb250U3R5bGUsCgkJCShzaXplb2YgYXR0cmliVGFncykvc2l6ZW9mKEFUU1VBdHRyaWJ1dGVUYWcpLAoJCQlhdHRyaWJUYWdzLCBhdHRyaWJTaXplcywgYXR0cmliVmFsdWVzKSAhPSBub0VycikKCSAgICB7CiMgaWZuZGVmIE5ERUJVRwoJCWZwcmludGYoc3RkZXJyLCAiY291bGRuJ3Qgc2V0IGZvbnQgc3R5bGVcbiIpOwojIGVuZGlmCgkJQVRTVURpc3Bvc2VTdHlsZShnRm9udFN0eWxlKTsKCQlnRm9udFN0eWxlID0gTlVMTDsKCSAgICB9Cgl9CgogICAgfQoKICAgIGlmIChwX21hY2F0c3VpICYmICFnSXNGb250RmFsbGJhY2tTZXQpCiAgICB7CgkvKiBTZXR1cCBhdXRvbWF0aWMgZm9udCBzdWJzdGl0dXRpb24uIFRoZSB1c2VyJ3MgZ3VpZm9udHdpZGUKCSAqIGlzIHRyaWVkIGZpcnN0LCB0aGVuIHRoZSBzeXN0ZW0gdHJpZXMgb3RoZXIgZm9udHMuICovCi8qCglBVFNVQXR0cmlidXRlVGFnIGZhbGxiYWNrVGFnc1tdID0geyBrQVRTVUxpbmVGb250RmFsbGJhY2tzVGFnIH07CglCeXRlQ291bnQgZmFsbGJhY2tTaXplc1tdID0geyBzaXplb2YoQVRTVUZvbnRGYWxsYmFja3MpIH07CglBVFNVQ3JlYXRlRm9udEZhbGxiYWNrcygmZ0ZvbnRGYWxsYmFja3MpOwoJQVRTVVNldE9iakZvbnRGYWxsYmFja3MoZ0ZvbnRGYWxsYmFja3MsICk7CiovCglpZiAoZ3VpLndpZGVfZm9udCkKCXsKCSAgICBBVFNVRm9udElEIGZhbGxiYWNrRm9udHM7CgkgICAgZ0lzRm9udEZhbGxiYWNrU2V0ID0gVFJVRTsKCgkgICAgaWYgKEZNR2V0Rm9udEZyb21Gb250RmFtaWx5SW5zdGFuY2UoCgkJCShndWkud2lkZV9mb250ICYgMHhGRkZGKSwKCQkJMCwKCQkJJmZhbGxiYWNrRm9udHMsCgkJCU5VTEwpID09IG5vRXJyKQoJICAgIHsKCQlBVFNVU2V0Rm9udEZhbGxiYWNrcygoc2l6ZW9mIGZhbGxiYWNrRm9udHMpL3NpemVvZihBVFNVRm9udElEKSwgJmZhbGxiYWNrRm9udHMsIGtBVFNVU2VxdWVudGlhbEZhbGxiYWNrc1ByZWZlcnJlZCk7CgkgICAgfQovKgoJQVRTVUF0dHJpYnV0ZVZhbHVlUHRyIGZhbGxiYWNrVmFsdWVzW10gPSB7IH07CiovCgl9CiAgICB9CiNlbmRpZgogICAgVGV4dFNpemUoZm9udCA+PiAxNik7CiAgICBUZXh0Rm9udChmb250ICYgMHhGRkZGKTsKfQoKLyoKICogSWYgYSBmb250IGlzIG5vdCBnb2luZyB0byBiZSB1c2VkLCBmcmVlIGl0cyBzdHJ1Y3R1cmUuCiAqLwogICAgdm9pZApndWlfbWNoX2ZyZWVfZm9udChmb250KQogICAgR3VpRm9udAlmb250Owp7CiAgICAvKgogICAgICogRnJlZSBmb250IHdoZW4gImZvbnQiIGlzIG5vdCAwLgogICAgICogTm90aGluZyB0byBkbyBpbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiwgc2luY2UKICAgICAqIG5vdGhpbmcgaXMgYWxsb2NhdGVkIGZvciBlYWNoIGZvbnQgdXNlZC4KICAgICAqLwp9CgogICAgc3RhdGljIGludApoZXhfZGlnaXQoaW50IGMpCnsKICAgIGlmIChpc2RpZ2l0KGMpKQoJcmV0dXJuIGMgLSAnMCc7CiAgICBjID0gVE9MT1dFUl9BU0MoYyk7CiAgICBpZiAoYyA+PSAnYScgJiYgYyA8PSAnZicpCglyZXR1cm4gYyAtICdhJyArIDEwOwogICAgcmV0dXJuIC0xMDAwOwp9CgovKgogKiBSZXR1cm4gdGhlIFBpeGVsIHZhbHVlIChjb2xvcikgZm9yIHRoZSBnaXZlbiBjb2xvciBuYW1lLiAgVGhpcyByb3V0aW5lIHdhcwogKiBwcmV0dHkgbXVjaCB0YWtlbiBmcm9tIGV4YW1wbGUgY29kZSBpbiB0aGUgU2lsaWNvbiBHcmFwaGljcyBPU0YvTW90aWYKICogUHJvZ3JhbW1lcidzIEd1aWRlLgogKiBSZXR1cm4gSU5WQUxDT0xPUiB3aGVuIGZhaWxlZC4KICovCiAgICBndWljb2xvcl9UCmd1aV9tY2hfZ2V0X2NvbG9yKGNoYXJfdSAqbmFtZSkKewogICAgLyogVE9ETzogQWRkIHN1cHBvcnQgZm9yIHRoZSBuZXcgbmFtZWQgY29sb3Igb2YgTWFjT1MgOAogICAgICovCiAgICBSR0JDb2xvcglNYWNDb2xvcjsKLy8gICAgZ3VpY29sb3JfVAljb2xvciA9IDA7CgogICAgdHlwZWRlZiBzdHJ1Y3QgZ3VpY29sb3JfdFRhYmxlCiAgICB7CgljaGFyCSAgICAqbmFtZTsKCWd1aWNvbG9yX1QgIGNvbG9yOwogICAgfSBndWljb2xvcl90VGFibGU7CgogICAgLyoKICAgICAqIFRoZSBjb21tZW50IGF0IHRoZSBlbmQgb2YgZWFjaCBsaW5lIGlzIHRoZSBzb3VyY2UKICAgICAqIChNYWMsIFdpbmRvdywgVW5peCkgYW5kIHRoZSBudW1iZXIgaXMgdGhlIHVuaXggcmdiLnR4dCB2YWx1ZQogICAgICovCiAgICBzdGF0aWMgZ3VpY29sb3JfdFRhYmxlIHRhYmxlW10gPQogICAgewoJeyJCbGFjayIsCVJHQigweDAwLCAweDAwLCAweDAwKX0sCgl7ImRhcmtncmF5IiwJUkdCKDB4ODAsIDB4ODAsIDB4ODApfSwgLypXKi8KCXsiZGFya2dyZXkiLAlSR0IoMHg4MCwgMHg4MCwgMHg4MCl9LCAvKlcqLwoJeyJHcmF5IiwJUkdCKDB4QzAsIDB4QzAsIDB4QzApfSwgLypXKi8KCXsiR3JleSIsCVJHQigweEMwLCAweEMwLCAweEMwKX0sIC8qVyovCgl7ImxpZ2h0Z3JheSIsCVJHQigweEUwLCAweEUwLCAweEUwKX0sIC8qVyovCgl7ImxpZ2h0Z3JleSIsCVJHQigweEUwLCAweEUwLCAweEUwKX0sIC8qVyovCgl7ImdyYXkxMCIsCVJHQigweDFBLCAweDFBLCAweDFBKX0sIC8qVyovCgl7ImdyZXkxMCIsCVJHQigweDFBLCAweDFBLCAweDFBKX0sIC8qVyovCgl7ImdyYXkyMCIsCVJHQigweDMzLCAweDMzLCAweDMzKX0sIC8qVyovCgl7ImdyZXkyMCIsCVJHQigweDMzLCAweDMzLCAweDMzKX0sIC8qVyovCgl7ImdyYXkzMCIsCVJHQigweDRELCAweDRELCAweDREKX0sIC8qVyovCgl7ImdyZXkzMCIsCVJHQigweDRELCAweDRELCAweDREKX0sIC8qVyovCgl7ImdyYXk0MCIsCVJHQigweDY2LCAweDY2LCAweDY2KX0sIC8qVyovCgl7ImdyZXk0MCIsCVJHQigweDY2LCAweDY2LCAweDY2KX0sIC8qVyovCgl7ImdyYXk1MCIsCVJHQigweDdGLCAweDdGLCAweDdGKX0sIC8qVyovCgl7ImdyZXk1MCIsCVJHQigweDdGLCAweDdGLCAweDdGKX0sIC8qVyovCgl7ImdyYXk2MCIsCVJHQigweDk5LCAweDk5LCAweDk5KX0sIC8qVyovCgl7ImdyZXk2MCIsCVJHQigweDk5LCAweDk5LCAweDk5KX0sIC8qVyovCgl7ImdyYXk3MCIsCVJHQigweEIzLCAweEIzLCAweEIzKX0sIC8qVyovCgl7ImdyZXk3MCIsCVJHQigweEIzLCAweEIzLCAweEIzKX0sIC8qVyovCgl7ImdyYXk4MCIsCVJHQigweENDLCAweENDLCAweENDKX0sIC8qVyovCgl7ImdyZXk4MCIsCVJHQigweENDLCAweENDLCAweENDKX0sIC8qVyovCgl7ImdyYXk5MCIsCVJHQigweEU1LCAweEU1LCAweEU1KX0sIC8qVyovCgl7ImdyZXk5MCIsCVJHQigweEU1LCAweEU1LCAweEU1KX0sIC8qVyovCgl7IndoaXRlIiwJUkdCKDB4RkYsIDB4RkYsIDB4RkYpfSwKCXsiZGFya3JlZCIsCVJHQigweDgwLCAweDAwLCAweDAwKX0sIC8qVyovCgl7InJlZCIsCQlSR0IoMHhERCwgMHgwOCwgMHgwNil9LCAvKk0qLwoJeyJsaWdodHJlZCIsCVJHQigweEZGLCAweEEwLCAweEEwKX0sIC8qVyovCgl7IkRhcmtCbHVlIiwJUkdCKDB4MDAsIDB4MDAsIDB4ODApfSwgLypXKi8KCXsiQmx1ZSIsCVJHQigweDAwLCAweDAwLCAweEQ0KX0sIC8qTSovCgl7ImxpZ2h0Ymx1ZSIsCVJHQigweEEwLCAweEEwLCAweEZGKX0sIC8qVyovCgl7IkRhcmtHcmVlbiIsCVJHQigweDAwLCAweDgwLCAweDAwKX0sIC8qVyovCgl7IkdyZWVuIiwJUkdCKDB4MDAsIDB4NjQsIDB4MTEpfSwgLypNKi8KCXsibGlnaHRncmVlbiIsCVJHQigweEEwLCAweEZGLCAweEEwKX0sIC8qVyovCgl7IkRhcmtDeWFuIiwJUkdCKDB4MDAsIDB4ODAsIDB4ODApfSwgLypXID8weDMwN0Q3RSAqLwoJeyJjeWFuIiwJUkdCKDB4MDIsIDB4QUIsIDB4RUEpfSwgLypNKi8KCXsibGlnaHRjeWFuIiwJUkdCKDB4QTAsIDB4RkYsIDB4RkYpfSwgLypXKi8KCXsiZGFya21hZ2VudGEiLAlSR0IoMHg4MCwgMHgwMCwgMHg4MCl9LCAvKlcqLwoJeyJtYWdlbnRhIiwJUkdCKDB4RjIsIDB4MDgsIDB4ODQpfSwgLypNKi8KCXsibGlnaHRtYWdlbnRhIixSR0IoMHhGMCwgMHhBMCwgMHhGMCl9LCAvKlcqLwoJeyJicm93biIsCVJHQigweDgwLCAweDQwLCAweDQwKX0sIC8qVyovCgl7InllbGxvdyIsCVJHQigweEZDLCAweEYzLCAweDA1KX0sIC8qTSovCgl7ImxpZ2h0eWVsbG93IiwJUkdCKDB4RkYsIDB4RkYsIDB4QTApfSwgLypNKi8KCXsiZGFya3llbGxvdyIsCVJHQigweEJCLCAweEJCLCAweDAwKX0sIC8qVSovCgl7IlNlYUdyZWVuIiwJUkdCKDB4MkUsIDB4OEIsIDB4NTcpfSwgLypXIDB4NEU4OTc1ICovCgl7Im9yYW5nZSIsCVJHQigweEZDLCAweDgwLCAweDAwKX0sIC8qVyAweEY4N0ExNyAqLwoJeyJQdXJwbGUiLAlSR0IoMHhBMCwgMHgyMCwgMHhGMCl9LCAvKlcgMHg4ZTM1ZTUgKi8KCXsiU2xhdGVCbHVlIiwJUkdCKDB4NkEsIDB4NUEsIDB4Q0QpfSwgLypXIDB4NzM3Q0ExICovCgl7IlZpb2xldCIsCVJHQigweDhELCAweDM4LCAweEM5KX0sIC8qVSovCiAgICB9OwoKICAgIGludAkJciwgZywgYjsKICAgIGludAkJaTsKCiAgICBpZiAobmFtZVswXSA9PSAnIycgJiYgc3RybGVuKChjaGFyICopIG5hbWUpID09IDcpCiAgICB7CgkvKiBOYW1lIGlzIGluICIjcnJnZ2JiIiBmb3JtYXQgKi8KCXIgPSBoZXhfZGlnaXQobmFtZVsxXSkgKiAxNiArIGhleF9kaWdpdChuYW1lWzJdKTsKCWcgPSBoZXhfZGlnaXQobmFtZVszXSkgKiAxNiArIGhleF9kaWdpdChuYW1lWzRdKTsKCWIgPSBoZXhfZGlnaXQobmFtZVs1XSkgKiAxNiArIGhleF9kaWdpdChuYW1lWzZdKTsKCWlmIChyIDwgMCB8fCBnIDwgMCB8fCBiIDwgMCkKCSAgICByZXR1cm4gSU5WQUxDT0xPUjsKCXJldHVybiBSR0IociwgZywgYik7CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAoU1RSSUNNUChuYW1lLCAiaGlsaXRlIikgPT0gMCkKCXsKCSAgICBMTUdldEhpbGl0ZVJHQigmTWFjQ29sb3IpOwoJICAgIHJldHVybiAoUkdCKE1hY0NvbG9yLnJlZCA+PiA4LCBNYWNDb2xvci5ncmVlbiA+PiA4LCBNYWNDb2xvci5ibHVlID4+IDgpKTsKCX0KCS8qIENoZWNrIGlmIHRoZSBuYW1lIGlzIG9uZSBvZiB0aGUgY29sb3JzIHdlIGtub3cgKi8KCWZvciAoaSA9IDA7IGkgPCBzaXplb2YodGFibGUpIC8gc2l6ZW9mKHRhYmxlWzBdKTsgaSsrKQoJICAgIGlmIChTVFJJQ01QKG5hbWUsIHRhYmxlW2ldLm5hbWUpID09IDApCgkJcmV0dXJuIHRhYmxlW2ldLmNvbG9yOwogICAgfQoKICAgIC8qCiAgICAgKiBMYXN0IGF0dGVtcHQuIExvb2sgaW4gdGhlIGZpbGUgIiRWSU0vcmdiLnR4dCIuCiAgICAgKi8KICAgIHsKI2RlZmluZSBMSU5FX0xFTiAxMDAKCUZJTEUJKmZkOwoJY2hhcglsaW5lW0xJTkVfTEVOXTsKCWNoYXJfdQkqZm5hbWU7CgoJZm5hbWUgPSBleHBhbmRfZW52X3NhdmUoKGNoYXJfdSAqKSIkVklNUlVOVElNRS9yZ2IudHh0Iik7CglpZiAoZm5hbWUgPT0gTlVMTCkKCSAgICByZXR1cm4gSU5WQUxDT0xPUjsKCglmZCA9IGZvcGVuKChjaGFyICopZm5hbWUsICJydCIpOwoJdmltX2ZyZWUoZm5hbWUpOwoJaWYgKGZkID09IE5VTEwpCgkgICAgcmV0dXJuIElOVkFMQ09MT1I7CgoJd2hpbGUgKCFmZW9mKGZkKSkKCXsKCSAgICBpbnQJCWxlbjsKCSAgICBpbnQJCXBvczsKCSAgICBjaGFyCSpjb2xvcjsKCgkgICAgZmdldHMobGluZSwgTElORV9MRU4sIGZkKTsKCSAgICBsZW4gPSBzdHJsZW4obGluZSk7CgoJICAgIGlmIChsZW4gPD0gMSB8fCBsaW5lW2xlbi0xXSAhPSAnXG4nKQoJCWNvbnRpbnVlOwoKCSAgICBsaW5lW2xlbi0xXSA9ICdcMCc7CgoJICAgIGkgPSBzc2NhbmYobGluZSwgIiVkICVkICVkICVuIiwgJnIsICZnLCAmYiwgJnBvcyk7CgkgICAgaWYgKGkgIT0gMykKCQljb250aW51ZTsKCgkgICAgY29sb3IgPSBsaW5lICsgcG9zOwoKCSAgICBpZiAoU1RSSUNNUChjb2xvciwgbmFtZSkgPT0gMCkKCSAgICB7CgkJZmNsb3NlKGZkKTsKCQlyZXR1cm4gKGd1aWNvbG9yX1QpIFJHQihyLCBnLCBiKTsKCSAgICB9Cgl9CglmY2xvc2UoZmQpOwogICAgfQoKICAgIHJldHVybiBJTlZBTENPTE9SOwp9CgovKgogKiBTZXQgdGhlIGN1cnJlbnQgdGV4dCBmb3JlZ3JvdW5kIGNvbG9yLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zZXRfZmdfY29sb3IoZ3VpY29sb3JfVCBjb2xvcikKewogICAgUkdCQ29sb3IgVGhlQ29sb3I7CgogICAgVGhlQ29sb3IucmVkID0gUmVkKGNvbG9yKSAqIDB4MDEwMTsKICAgIFRoZUNvbG9yLmdyZWVuID0gR3JlZW4oY29sb3IpICogMHgwMTAxOwogICAgVGhlQ29sb3IuYmx1ZSA9IEJsdWUoY29sb3IpICogMHgwMTAxOwoKICAgIFJHQkZvcmVDb2xvcigmVGhlQ29sb3IpOwp9CgovKgogKiBTZXQgdGhlIGN1cnJlbnQgdGV4dCBiYWNrZ3JvdW5kIGNvbG9yLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zZXRfYmdfY29sb3IoZ3VpY29sb3JfVCBjb2xvcikKewogICAgUkdCQ29sb3IgVGhlQ29sb3I7CgogICAgVGhlQ29sb3IucmVkID0gUmVkKGNvbG9yKSAqIDB4MDEwMTsKICAgIFRoZUNvbG9yLmdyZWVuID0gR3JlZW4oY29sb3IpICogMHgwMTAxOwogICAgVGhlQ29sb3IuYmx1ZSA9IEJsdWUoY29sb3IpICogMHgwMTAxOwoKICAgIFJHQkJhY2tDb2xvcigmVGhlQ29sb3IpOwp9CgpSR0JDb2xvciBzcGVjaWFsQ29sb3I7CgovKgogKiBTZXQgdGhlIGN1cnJlbnQgdGV4dCBzcGVjaWFsIGNvbG9yLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zZXRfc3BfY29sb3IoZ3VpY29sb3JfVCBjb2xvcikKewogICAgc3BlY2lhbENvbG9yLnJlZCA9IFJlZChjb2xvcikgKiAweDAxMDE7CiAgICBzcGVjaWFsQ29sb3IuZ3JlZW4gPSBHcmVlbihjb2xvcikgKiAweDAxMDE7CiAgICBzcGVjaWFsQ29sb3IuYmx1ZSA9IEJsdWUoY29sb3IpICogMHgwMTAxOwp9CgovKgogKiBEcmF3IHVuZGVyY3VybCBhdCB0aGUgYm90dG9tIG9mIHRoZSBjaGFyYWN0ZXIgY2VsbC4KICovCiAgICBzdGF0aWMgdm9pZApkcmF3X3VuZGVyY3VybChpbnQgZmxhZ3MsIGludCByb3csIGludCBjb2wsIGludCBjZWxscykKewogICAgaW50CQkJeDsKICAgIGludAkJCW9mZnNldDsKICAgIGNvbnN0IHN0YXRpYyBpbnQJdmFsWzhdID0gezEsIDAsIDAsIDAsIDEsIDIsIDIsIDIgfTsKICAgIGludAkJCXkgPSBGSUxMX1kocm93ICsgMSkgLSAxOwoKICAgIFJHQkZvcmVDb2xvcigmc3BlY2lhbENvbG9yKTsKCiAgICBvZmZzZXQgPSB2YWxbRklMTF9YKGNvbCkgJSA4XTsKICAgIE1vdmVUbyhGSUxMX1goY29sKSwgeSAtIG9mZnNldCk7CgogICAgZm9yICh4ID0gRklMTF9YKGNvbCk7IHggPCBGSUxMX1goY29sICsgY2VsbHMpOyArK3gpCiAgICB7CglvZmZzZXQgPSB2YWxbeCAlIDhdOwoJTGluZVRvKHgsIHkgLSBvZmZzZXQpOwogICAgfQp9CgoKICAgIHN0YXRpYyB2b2lkCmRyYXdfc3RyaW5nX1FEKGludCByb3csIGludCBjb2wsIGNoYXJfdSAqcywgaW50IGxlbiwgaW50IGZsYWdzKQp7CiNpZmRlZiBGRUFUX01CWVRFCiAgICBjaGFyX3UJKnRvZnJlZSA9IE5VTEw7CgogICAgaWYgKG91dHB1dF9jb252LnZjX3R5cGUgIT0gQ09OVl9OT05FKQogICAgewoJdG9mcmVlID0gc3RyaW5nX2NvbnZlcnQoJm91dHB1dF9jb252LCBzLCAmbGVuKTsKCWlmICh0b2ZyZWUgIT0gTlVMTCkKCSAgICBzID0gdG9mcmVlOwogICAgfQojZW5kaWYKCiAgICAvKgogICAgICogT24gT1MgWCwgdHJ5IHVzaW5nIFF1YXJ0ei1zdHlsZSB0ZXh0IGFudGlhbGlhc2luZy4KICAgICAqLwogICAgaWYgKGdNYWNTeXN0ZW1WZXJzaW9uID49IDB4MTAyMCkKICAgIHsKCS8qIFF1YXJ0eiBhbnRpYWxpYXNpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT1MgMTAuMiBhbmQgbGF0ZXIuICovCglVSW50MzIgcWRfZmxhZ3MgPSAocF9hbnRpYWxpYXMgPwoJCQkgICAgIGtRRFVzZUNHVGV4dFJlbmRlcmluZyB8IGtRRFVzZUNHVGV4dE1ldHJpY3MgOiAwKTsKCVFEU3dhcFRleHRGbGFncyhxZF9mbGFncyk7CiAgICB9CgogICAgLyoKICAgICAqIFdoZW4gYW50aWFsaWFzaW5nIHdlJ3JlIHVzaW5nIHNyY09yIG1vZGUsIHdlIGhhdmUgdG8gY2xlYXIgdGhlIGJsb2NrCiAgICAgKiBiZWZvcmUgZHJhd2luZyB0aGUgdGV4dC4KICAgICAqIEFsc28gbmVlZGVkIHdoZW4gJ2xpbmVzcGFjZScgaXMgbm9uLXplcm8gdG8gcmVtb3ZlIHRoZSBjdXJzb3IgYW5kCiAgICAgKiB1bmRlcmxpbmluZy4KICAgICAqIEJ1dCBub3Qgd2hlbiBkcmF3aW5nIHRyYW5zcGFyZW50bHkuCiAgICAgKiBUaGUgZm9sbG93aW5nIGlzIGxpa2UgY2FsbGluZyBndWlfbWNoX2NsZWFyX2Jsb2NrKHJvdywgY29sLCByb3csIGNvbCArCiAgICAgKiBsZW4gLSAxKSwgYnV0IHdpdGhvdXQgc2V0dGluZyB0aGUgYmcgY29sb3IgdG8gZ3VpLmJhY2tfcGl4ZWwuCiAgICAgKi8KICAgIGlmICgoKGdNYWNTeXN0ZW1WZXJzaW9uID49IDB4MTAyMCAmJiBwX2FudGlhbGlhcykgfHwgcF9saW5lc3BhY2UgIT0gMCkKCSAgICAmJiAhKGZsYWdzICYgRFJBV19UUkFOU1ApKQogICAgewoJUmVjdCByYzsKCglyYy5sZWZ0ID0gRklMTF9YKGNvbCk7CglyYy50b3AgPSBGSUxMX1kocm93KTsKI2lmZGVmIEZFQVRfTUJZVEUKCS8qIE11bHRpYnl0ZSBjb21wdXRhdGlvbiB0YWtlbiBmcm9tIGd1aV93MzIuYyAqLwoJaWYgKGhhc19tYnl0ZSkKCXsKCSAgICBpbnQgY2VsbF9sZW4gPSAwOwoJICAgIGludCBuOwoKCSAgICAvKiBDb21wdXRlIHRoZSBsZW5ndGggaW4gZGlzcGxheSBjZWxscy4gKi8KCSAgICBmb3IgKG4gPSAwOyBuIDwgbGVuOyBuICs9IE1CX0JZVEUyTEVOKHNbbl0pKQoJCWNlbGxfbGVuICs9ICgqbWJfcHRyMmNlbGxzKShzICsgbik7CgkgICAgcmMucmlnaHQgPSBGSUxMX1goY29sICsgY2VsbF9sZW4pOwoJfQoJZWxzZQojZW5kaWYKCXJjLnJpZ2h0ID0gRklMTF9YKGNvbCArIGxlbikgKyAoY29sICsgbGVuID09IENvbHVtbnMpOwoJcmMuYm90dG9tID0gRklMTF9ZKHJvdyArIDEpOwoJRXJhc2VSZWN0KCZyYyk7CiAgICB9CgogICAgaWYgKGdNYWNTeXN0ZW1WZXJzaW9uID49IDB4MTAyMCAmJiBwX2FudGlhbGlhcykKICAgIHsKCVN0eWxlUGFyYW1ldGVyIGZhY2U7CgoJZmFjZSA9IG5vcm1hbDsKCWlmIChmbGFncyAmIERSQVdfQk9MRCkKCSAgICBmYWNlIHw9IGJvbGQ7CglpZiAoZmxhZ3MgJiBEUkFXX1VOREVSTCkKCSAgICBmYWNlIHw9IHVuZGVybGluZTsKCVRleHRGYWNlKGZhY2UpOwoKCS8qIFF1YXJ0eiBhbnRpYWxpYXNpbmcgd29ya3Mgb25seSBpbiBzcmNPciB0cmFuc2ZlciBtb2RlLiAqLwoJVGV4dE1vZGUoc3JjT3IpOwoKCU1vdmVUbyhURVhUX1goY29sKSwgVEVYVF9ZKHJvdykpOwoJRHJhd1RleHQoKGNoYXIqKXMsIDAsIGxlbik7CiAgICB9CiAgICBlbHNlCiAgICB7CgkvKiBVc2Ugb2xkLXN0eWxlLCBub24tYW50aWFsaWFzZWQgUXVpY2tEcmF3IHRleHQgcmVuZGVyaW5nLiAqLwoJVGV4dE1vZGUoc3JjQ29weSk7CglUZXh0RmFjZShub3JtYWwpOwoKICAgIC8qICBTZWxlY3RGb250KGhkYywgZ3VpLmN1cnJGb250KTsgKi8KCglpZiAoZmxhZ3MgJiBEUkFXX1RSQU5TUCkKCXsKCSAgICBUZXh0TW9kZShzcmNPcik7Cgl9CgoJTW92ZVRvKFRFWFRfWChjb2wpLCBURVhUX1kocm93KSk7CglEcmF3VGV4dCgoY2hhciAqKXMsIDAsIGxlbik7CgoJaWYgKGZsYWdzICYgRFJBV19CT0xEKQoJewoJICAgIFRleHRNb2RlKHNyY09yKTsKCSAgICBNb3ZlVG8oVEVYVF9YKGNvbCkgKyAxLCBURVhUX1kocm93KSk7CgkgICAgRHJhd1RleHQoKGNoYXIgKilzLCAwLCBsZW4pOwoJfQoKCWlmIChmbGFncyAmIERSQVdfVU5ERVJMKQoJewoJICAgIE1vdmVUbyhGSUxMX1goY29sKSwgRklMTF9ZKHJvdyArIDEpIC0gMSk7CgkgICAgTGluZVRvKEZJTExfWChjb2wgKyBsZW4pIC0gMSwgRklMTF9ZKHJvdyArIDEpIC0gMSk7Cgl9CiAgICB9CgogICAgaWYgKGZsYWdzICYgRFJBV19VTkRFUkMpCglkcmF3X3VuZGVyY3VybChmbGFncywgcm93LCBjb2wsIGxlbik7CgojaWZkZWYgRkVBVF9NQllURQogICAgdmltX2ZyZWUodG9mcmVlKTsKI2VuZGlmCn0KCiNpZmRlZiBVU0VfQVRTVUlfRFJBV0lORwoKICAgIHN0YXRpYyB2b2lkCmRyYXdfc3RyaW5nX0FUU1VJKGludCByb3csIGludCBjb2wsIGNoYXJfdSAqcywgaW50IGxlbiwgaW50IGZsYWdzKQp7CiAgICAvKiBBVFNVSSByZXF1aXJlcyB1dGYtMTYgc3RyaW5ncyAqLwogICAgVW5pQ2hhckNvdW50IHV0ZjE2X2xlbjsKICAgIFVuaUNoYXIgKnRvZnJlZSA9IG1hY19lbmNfdG9fdXRmMTYocywgbGVuLCAoc2l6ZV90ICopJnV0ZjE2X2xlbik7CiAgICB1dGYxNl9sZW4gLz0gc2l6ZW9mKFVuaUNoYXIpOwoKICAgIC8qIC0gQVRTVUkgYXV0b21hdGljYWxseSBhbnRpYWxpYXNlcyB0ZXh0IChTb21lb25lKQogICAgICogLSBmb3Igc29tZSByZWFzb24gaXQgZG9lcyBub3Qgd29yay4uLiAoSnVzc2kpICovCgogICAgLyoKICAgICAqIFdoZW4gYW50aWFsaWFzaW5nIHdlJ3JlIHVzaW5nIHNyY09yIG1vZGUsIHdlIGhhdmUgdG8gY2xlYXIgdGhlIGJsb2NrCiAgICAgKiBiZWZvcmUgZHJhd2luZyB0aGUgdGV4dC4KICAgICAqIEFsc28gbmVlZGVkIHdoZW4gJ2xpbmVzcGFjZScgaXMgbm9uLXplcm8gdG8gcmVtb3ZlIHRoZSBjdXJzb3IgYW5kCiAgICAgKiB1bmRlcmxpbmluZy4KICAgICAqIEJ1dCBub3Qgd2hlbiBkcmF3aW5nIHRyYW5zcGFyZW50bHkuCiAgICAgKiBUaGUgZm9sbG93aW5nIGlzIGxpa2UgY2FsbGluZyBndWlfbWNoX2NsZWFyX2Jsb2NrKHJvdywgY29sLCByb3csIGNvbCArCiAgICAgKiBsZW4gLSAxKSwgYnV0IHdpdGhvdXQgc2V0dGluZyB0aGUgYmcgY29sb3IgdG8gZ3VpLmJhY2tfcGl4ZWwuCiAgICAgKi8KICAgIGlmICgoZmxhZ3MgJiBEUkFXX1RSQU5TUCkgPT0gMCkKICAgIHsKCVJlY3QgcmM7CgoJcmMubGVmdCA9IEZJTExfWChjb2wpOwoJcmMudG9wID0gRklMTF9ZKHJvdyk7CgkvKiBNdWx0aWJ5dGUgY29tcHV0YXRpb24gdGFrZW4gZnJvbSBndWlfdzMyLmMgKi8KCWlmIChoYXNfbWJ5dGUpCgl7CgkgICAgaW50IGNlbGxfbGVuID0gMDsKCSAgICBpbnQgbjsKCgkgICAgLyogQ29tcHV0ZSB0aGUgbGVuZ3RoIGluIGRpc3BsYXkgY2VsbHMuICovCgkgICAgZm9yIChuID0gMDsgbiA8IGxlbjsgbiArPSBNQl9CWVRFMkxFTihzW25dKSkKCQljZWxsX2xlbiArPSAoKm1iX3B0cjJjZWxscykocyArIG4pOwoJICAgIHJjLnJpZ2h0ID0gRklMTF9YKGNvbCArIGNlbGxfbGVuKTsKCX0KCWVsc2UKCSAgICByYy5yaWdodCA9IEZJTExfWChjb2wgKyBsZW4pICsgKGNvbCArIGxlbiA9PSBDb2x1bW5zKTsKCglyYy5ib3R0b20gPSBGSUxMX1kocm93ICsgMSk7CglFcmFzZVJlY3QoJnJjKTsKICAgIH0KCiAgICB7CgkvKiBVc2Ugb2xkLXN0eWxlLCBub24tYW50aWFsaWFzZWQgUXVpY2tEcmF3IHRleHQgcmVuZGVyaW5nLiAqLwoJVGV4dE1vZGUoc3JjQ29weSk7CglUZXh0RmFjZShub3JtYWwpOwoKICAgIC8qICBTZWxlY3RGb250KGhkYywgZ3VpLmN1cnJGb250KTsgKi8KCglpZiAoZmxhZ3MgJiBEUkFXX1RSQU5TUCkKCXsKCSAgICBUZXh0TW9kZShzcmNPcik7Cgl9CgoJTW92ZVRvKFRFWFRfWChjb2wpLCBURVhUX1kocm93KSk7CglBVFNVVGV4dExheW91dCB0ZXh0TGF5b3V0OwoKCWlmIChBVFNVQ3JlYXRlVGV4dExheW91dFdpdGhUZXh0UHRyKHRvZnJlZSwKCQkgICAga0FUU1VGcm9tVGV4dEJlZ2lubmluZywga0FUU1VUb1RleHRFbmQsCgkJICAgIHV0ZjE2X2xlbiwKCQkgICAgKGdGb250U3R5bGUgPyAxIDogMCksICZ1dGYxNl9sZW4sCgkJICAgIChnRm9udFN0eWxlID8gJmdGb250U3R5bGUgOiBOVUxMKSwKCQkgICAgJnRleHRMYXlvdXQpID09IG5vRXJyKQoJewoJICAgIEFUU1VTZXRUcmFuc2llbnRGb250TWF0Y2hpbmcodGV4dExheW91dCwgVFJVRSk7CgoJICAgIEFUU1VEcmF3VGV4dCh0ZXh0TGF5b3V0LAoJCSAgICBrQVRTVUZyb21UZXh0QmVnaW5uaW5nLCBrQVRTVVRvVGV4dEVuZCwKCQkgICAga0FUU1VVc2VHcmFmUG9ydFBlbkxvYywga0FUU1VVc2VHcmFmUG9ydFBlbkxvYyk7CgoJICAgIEFUU1VEaXNwb3NlVGV4dExheW91dCh0ZXh0TGF5b3V0KTsKCX0KICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBEUkFXX1VOREVSQykKCWRyYXdfdW5kZXJjdXJsKGZsYWdzLCByb3csIGNvbCwgbGVuKTsKCiAgICB2aW1fZnJlZSh0b2ZyZWUpOwp9CiNlbmRpZgoKICAgIHZvaWQKZ3VpX21jaF9kcmF3X3N0cmluZyhpbnQgcm93LCBpbnQgY29sLCBjaGFyX3UgKnMsIGludCBsZW4sIGludCBmbGFncykKewojaWYgZGVmaW5lZChVU0VfQVRTVUlfRFJBV0lORykKICAgIGlmIChwX21hY2F0c3VpKQoJZHJhd19zdHJpbmdfQVRTVUkocm93LCBjb2wsIHMsIGxlbiwgZmxhZ3MpOwogICAgZWxzZQojZW5kaWYKCWRyYXdfc3RyaW5nX1FEKHJvdywgY29sLCBzLCBsZW4sIGZsYWdzKTsKfQoKLyoKICogUmV0dXJuIE9LIGlmIHRoZSBrZXkgd2l0aCB0aGUgdGVybWNhcCBuYW1lICJuYW1lIiBpcyBzdXBwb3J0ZWQuCiAqLwogICAgaW50Cmd1aV9tY2hfaGFza2V5KGNoYXJfdSAqbmFtZSkKewogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgc3BlY2lhbF9rZXlzW2ldLmtleV9zeW0gIT0gKEtleVN5bSkwOyBpKyspCglpZiAobmFtZVswXSA9PSBzcGVjaWFsX2tleXNbaV0udmltX2NvZGUwICYmCgkJCQkJIG5hbWVbMV0gPT0gc3BlY2lhbF9rZXlzW2ldLnZpbV9jb2RlMSkKCSAgICByZXR1cm4gT0s7CiAgICByZXR1cm4gRkFJTDsKfQoKICAgIHZvaWQKZ3VpX21jaF9iZWVwKHZvaWQpCnsKICAgIFN5c0JlZXAoMSk7IC8qIFNob3VsZCB0aGlzIGJlIDA/ICg/Pz8/KSAqLwp9CgogICAgdm9pZApndWlfbWNoX2ZsYXNoKGludCBtc2VjKQp7CiAgICAvKiBEbyBhIHZpc3VhbCBiZWVwIGJ5IHJldmVyc2luZyB0aGUgZm9yZWdyb3VuZCBhbmQgYmFja2dyb3VuZCBjb2xvcnMgKi8KICAgIFJlY3QgICAgcmM7CgogICAgLyoKICAgICAqIE5vdGU6IEludmVydFJlY3QoKSBleGNsdWRlcyByaWdodCBhbmQgYm90dG9tIG9mIHJlY3RhbmdsZS4KICAgICAqLwogICAgcmMubGVmdCA9IDA7CiAgICByYy50b3AgPSAwOwogICAgcmMucmlnaHQgPSBndWkubnVtX2NvbHMgKiBndWkuY2hhcl93aWR0aDsKICAgIHJjLmJvdHRvbSA9IGd1aS5udW1fcm93cyAqIGd1aS5jaGFyX2hlaWdodDsKICAgIEludmVydFJlY3QoJnJjKTsKCiAgICB1aV9kZWxheSgobG9uZyltc2VjLCBUUlVFKTsJCS8qIHdhaXQgZm9yIHNvbWUgbXNlYyAqLwoKICAgIEludmVydFJlY3QoJnJjKTsKfQoKLyoKICogSW52ZXJ0IGEgcmVjdGFuZ2xlIGZyb20gcm93IHIsIGNvbHVtbiBjLCBmb3IgbnIgcm93cyBhbmQgbmMgY29sdW1ucy4KICovCiAgICB2b2lkCmd1aV9tY2hfaW52ZXJ0X3JlY3RhbmdsZShpbnQgciwgaW50IGMsIGludCBuciwgaW50IG5jKQp7CiAgICBSZWN0CXJjOwoKICAgIC8qCiAgICAgKiBOb3RlOiBJbnZlcnRSZWN0KCkgZXhjbHVkZXMgcmlnaHQgYW5kIGJvdHRvbSBvZiByZWN0YW5nbGUuCiAgICAgKi8KICAgIHJjLmxlZnQgPSBGSUxMX1goYyk7CiAgICByYy50b3AgPSBGSUxMX1kocik7CiAgICByYy5yaWdodCA9IHJjLmxlZnQgKyBuYyAqIGd1aS5jaGFyX3dpZHRoOwogICAgcmMuYm90dG9tID0gcmMudG9wICsgbnIgKiBndWkuY2hhcl9oZWlnaHQ7CiAgICBJbnZlcnRSZWN0KCZyYyk7Cn0KCi8qCiAqIEljb25pZnkgdGhlIEdVSSB3aW5kb3cuCiAqLwogICAgdm9pZApndWlfbWNoX2ljb25pZnkodm9pZCkKewogICAgLyogVE9ETzogZmluZCBvdXQgd2hhdCBjb3VsZCByZXBsYWNlIGljb25pZnkKICAgICAqCSAgICAgLXdpbmRvdyBzaGFkZT8KICAgICAqCSAgICAgLWhpZGUgYXBwbGljYXRpb24/CiAgICAgKi8KfQoKI2lmIGRlZmluZWQoRkVBVF9FVkFMKSB8fCBkZWZpbmVkKFBST1RPKQovKgogKiBCcmluZyB0aGUgVmltIHdpbmRvdyB0byB0aGUgZm9yZWdyb3VuZC4KICovCiAgICB2b2lkCmd1aV9tY2hfc2V0X2ZvcmVncm91bmQodm9pZCkKewogICAgLyogVE9ETyAqLwp9CiNlbmRpZgoKLyoKICogRHJhdyBhIGN1cnNvciB3aXRob3V0IGZvY3VzLgogKi8KICAgIHZvaWQKZ3VpX21jaF9kcmF3X2hvbGxvd19jdXJzb3IoZ3VpY29sb3JfVCBjb2xvcikKewogICAgUmVjdCByYzsKCiAgICAvKgogICAgICogTm90ZTogRnJhbWVSZWN0KCkgZXhjbHVkZXMgcmlnaHQgYW5kIGJvdHRvbSBvZiByZWN0YW5nbGUuCiAgICAgKi8KICAgIHJjLmxlZnQgPSBGSUxMX1goZ3VpLmNvbCk7CiAgICByYy50b3AgPSBGSUxMX1koZ3VpLnJvdyk7CiAgICByYy5yaWdodCA9IHJjLmxlZnQgKyBndWkuY2hhcl93aWR0aDsKI2lmZGVmIEZFQVRfTUJZVEUKICAgIGlmIChtYl9sZWZ0aGFsdmUoZ3VpLnJvdywgZ3VpLmNvbCkpCglyYy5yaWdodCArPSBndWkuY2hhcl93aWR0aDsKI2VuZGlmCiAgICByYy5ib3R0b20gPSByYy50b3AgKyBndWkuY2hhcl9oZWlnaHQ7CgogICAgZ3VpX21jaF9zZXRfZmdfY29sb3IoY29sb3IpOwoKICAgIEZyYW1lUmVjdCgmcmMpOwp9CgovKgogKiBEcmF3IHBhcnQgb2YgYSBjdXJzb3IsIG9ubHkgdyBwaXhlbHMgd2lkZSwgYW5kIGggcGl4ZWxzIGhpZ2guCiAqLwogICAgdm9pZApndWlfbWNoX2RyYXdfcGFydF9jdXJzb3IoaW50IHcsIGludCBoLCBndWljb2xvcl9UIGNvbG9yKQp7CiAgICBSZWN0IHJjOwoKI2lmZGVmIEZFQVRfUklHSFRMRUZUCiAgICAvKiB2ZXJ0aWNhbCBsaW5lIHNob3VsZCBiZSBvbiB0aGUgcmlnaHQgb2YgY3VycmVudCBwb2ludCAqLwogICAgaWYgKENVUlNPUl9CQVJfUklHSFQpCglyYy5sZWZ0ID0gRklMTF9YKGd1aS5jb2wgKyAxKSAtIHc7CiAgICBlbHNlCiNlbmRpZgoJcmMubGVmdCA9IEZJTExfWChndWkuY29sKTsKICAgIHJjLnRvcCA9IEZJTExfWShndWkucm93KSArIGd1aS5jaGFyX2hlaWdodCAtIGg7CiAgICByYy5yaWdodCA9IHJjLmxlZnQgKyB3OwogICAgcmMuYm90dG9tID0gcmMudG9wICsgaDsKCiAgICBndWlfbWNoX3NldF9mZ19jb2xvcihjb2xvcik7CgogICAgRnJhbWVSZWN0KCZyYyk7Ci8vICAgIFBhaW50UmVjdCgmcmMpOwp9CgoKCi8qCiAqIENhdGNoIHVwIHdpdGggYW55IHF1ZXVlZCBYIGV2ZW50cy4gIFRoaXMgbWF5IHB1dCBrZXlib2FyZCBpbnB1dCBpbnRvIHRoZQogKiBpbnB1dCBidWZmZXIsIGNhbGwgcmVzaXplIGNhbGwtYmFja3MsIHRyaWdnZXIgdGltZXJzIGV0Yy4gIElmIHRoZXJlIGlzCiAqIG5vdGhpbmcgaW4gdGhlIFggZXZlbnQgcXVldWUgKCYgbm8gdGltZXJzIHBlbmRpbmcpLCB0aGVuIHdlIHJldHVybgogKiBpbW1lZGlhdGVseS4KICovCiAgICB2b2lkCmd1aV9tY2hfdXBkYXRlKHZvaWQpCnsKICAgIC8qIFRPRE86IGZpbmQgd2hhdCB0byBkbwogICAgICoJICAgICBtYXliZSBjYWxsIGd1aV9tY2hfd2FpdF9mb3JfY2hhcnMgKDApCiAgICAgKgkgICAgIG1vcmUgbGlrZSBsb29rIGF0IEV2ZW50UXVldWUgdGhlbgogICAgICoJICAgICBjYWxsIGhlYXJ0IG9mIGd1aV9tY2hfd2FpdF9mb3JfY2hhcnM7CiAgICAgKgogICAgICoJaWYgKGV2ZW50dGhlcikKICAgICAqCSAgICBndWlfbWFjX2hhbmRsZV9ldmVudCgmZXZlbnQpOwogICAgICovCiAgICBFdmVudFJlY29yZCB0aGVFdmVudDsKCiAgICBpZiAoRXZlbnRBdmFpbChldmVyeUV2ZW50LCAmdGhlRXZlbnQpKQoJaWYgKHRoZUV2ZW50LndoYXQgIT0gbnVsbEV2ZW50KQoJICAgIGd1aV9tY2hfd2FpdF9mb3JfY2hhcnMoMCk7Cn0KCi8qCiAqIFNpbXBsZSB3cmFwcGVyIHRvIG5lZ2xlY3QgbW9yZSBlYXNpbHkgdGhlIHRpbWUKICogc3BlbnQgaW5zaWRlIFdhaXROZXh0RXZlbnQgd2hpbGUgcHJvZmlsaW5nLgogKi8KCiAgICBwYXNjYWwKICAgIEJvb2xlYW4KV2FpdE5leHRFdmVudFdycChFdmVudE1hc2sgZXZlbnRNYXNrLCBFdmVudFJlY29yZCAqdGhlRXZlbnQsIFVJbnQzMiBzbGVlcCwgUmduSGFuZGxlIG1vdXNlUmduKQp7CiAgICBpZiAoKChsb25nKSBzbGVlcCkgPCAtMSkKCXNsZWVwID0gMzI3Njc7CiAgICByZXR1cm4gV2FpdE5leHRFdmVudChldmVudE1hc2ssIHRoZUV2ZW50LCBzbGVlcCwgbW91c2VSZ24pOwp9CgovKgogKiBHVUkgaW5wdXQgcm91dGluZSBjYWxsZWQgYnkgZ3VpX3dhaXRfZm9yX2NoYXJzKCkuICBXYWl0cyBmb3IgYSBjaGFyYWN0ZXIKICogZnJvbSB0aGUga2V5Ym9hcmQuCiAqICB3dGltZSA9PSAtMQkgICAgV2FpdCBmb3JldmVyLgogKiAgd3RpbWUgPT0gMAkgICAgVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLgogKiAgd3RpbWUgPiAwCSAgICBXYWl0IHd0aW1lIG1pbGxpc2Vjb25kcyBmb3IgYSBjaGFyYWN0ZXIuCiAqIFJldHVybnMgT0sgaWYgYSBjaGFyYWN0ZXIgd2FzIGZvdW5kIHRvIGJlIGF2YWlsYWJsZSB3aXRoaW4gdGhlIGdpdmVuIHRpbWUsCiAqIG9yIEZBSUwgb3RoZXJ3aXNlLgogKi8KICAgIGludApndWlfbWNoX3dhaXRfZm9yX2NoYXJzKGludCB3dGltZSkKewogICAgRXZlbnRNYXNrCW1hc2sgID0gKGV2ZXJ5RXZlbnQpOwogICAgRXZlbnRSZWNvcmQgZXZlbnQ7CiAgICBsb25nCWVudHJ5VGljazsKICAgIGxvbmcJY3VycmVudFRpY2s7CiAgICBsb25nCXNsZWVwcHlUaWNrOwoKICAgIC8qIElmIHdlIGFyZSBwcm92aWRpbmcgbGlmZSBmZWVkYmFjayB3aXRoIHRoZSBzY3JvbGxiYXIsCiAgICAgKiB3ZSBkb24ndCB3YW50IHRvIHRyeSB0byB3YWl0IGZvciBhbiBldmVudCwgb3IgZWxzZQogICAgICogdGhlcmUgd29uJ3QgYmUgYW55IGxpZmUgZmVlZGJhY2suCiAgICAgKi8KICAgIGlmIChkcmFnZ2VkX3NiICE9IE5VTEwpCglyZXR1cm4gRkFJTDsKCS8qIFRPRE86IENoZWNrIGlmIEZBSUwgaXMgdGhlIHByb3BlciByZXR1cm4gY29kZSAqLwoKICAgIGVudHJ5VGljayA9IFRpY2tDb3VudCgpOwoKICAgIGFsbG93X3Njcm9sbGJhciA9IFRSVUU7CgogICAgZG8KICAgIHsKLyoJaWYgKGRyYWdSZWN0Q29udHJvbCA9PSBrQ3JlYXRlRW1wdHkpCgl7CgkgICAgZHJhZ1JnbiA9IE5VTEw7CgkgICAgZHJhZ1JlY3RDb250cm9sID0ga05vdGhpbmc7Cgl9CgllbHNlKi8gaWYgKGRyYWdSZWN0Q29udHJvbCA9PSBrQ3JlYXRlUmVjdCkKCXsKCSAgICBkcmFnUmduID0gY3Vyc29yUmduOwoJICAgIFJlY3RSZ24oZHJhZ1JnbiwgJmRyYWdSZWN0KTsKCSAgICBkcmFnUmVjdENvbnRyb2wgPSBrTm90aGluZzsKCX0KCS8qCgkgKiBEb24ndCB1c2UgZ3VpX21jaF91cGRhdGUoKSBiZWNhdXNlIHRoZW4gd2Ugd2lsbCBzcGluLWxvY2sgdW50aWwgYQoJICogY2hhciBhcnJpdmVzLCBpbnN0ZWFkIHdlIHVzZSBXYWl0TmV4dEV2ZW50V3JwKCkgdG8gaGFuZyB1bnRpbCBhbgoJICogZXZlbnQgYXJyaXZlcy4gIE5vIG5lZWQgdG8gY2hlY2sgZm9yIGlucHV0X2J1Zl9mdWxsIGJlY2F1c2Ugd2UgYXJlCgkgKiByZXR1cm5pbmcgYXMgc29vbiBhcyBpdCBjb250YWlucyBhIHNpbmdsZSBjaGFyLgoJICovCgkvKiBUT0RPOiByZWR1Y2Ugd3RpbWUgYWNjb3JkaW5seT8/PyAgKi8KCWlmICh3dGltZSA+IC0xKQoJICAgIHNsZWVwcHlUaWNrID0gNjAqd3RpbWUvMTAwMDsKCWVsc2UKCSAgICBzbGVlcHB5VGljayA9IDMyNzY3OwoJaWYgKFdhaXROZXh0RXZlbnRXcnAobWFzaywgJmV2ZW50LCBzbGVlcHB5VGljaywgZHJhZ1JnbikpCgl7CgkJZ3VpX21hY19oYW5kbGVfZXZlbnQoJmV2ZW50KTsKCSAgICBpZiAoaW5wdXRfYXZhaWxhYmxlKCkpCgkgICAgewoJCWFsbG93X3Njcm9sbGJhciA9IEZBTFNFOwoJCXJldHVybiBPSzsKCSAgICB9Cgl9CgljdXJyZW50VGljayA9IFRpY2tDb3VudCgpOwogICAgfQogICAgd2hpbGUgKCh3dGltZSA9PSAtMSkgfHwgKChjdXJyZW50VGljayAtIGVudHJ5VGljaykgPCA2MCp3dGltZS8xMDAwKSk7CgogICAgYWxsb3dfc2Nyb2xsYmFyID0gRkFMU0U7CiAgICByZXR1cm4gRkFJTDsKfQoKLyoKICogT3V0cHV0IHJvdXRpbmVzLgogKi8KCi8qIEZsdXNoIGFueSBvdXRwdXQgdG8gdGhlIHNjcmVlbiAqLwogICAgdm9pZApndWlfbWNoX2ZsdXNoKHZvaWQpCnsKICAgIC8qIFRPRE86IElzIGFueXRoaW5nIG5lZWRlZCBoZXJlPyAqLwp9CgovKgogKiBDbGVhciBhIHJlY3Rhbmd1bGFyIHJlZ2lvbiBvZiB0aGUgc2NyZWVuIGZyb20gdGV4dCBwb3MgKHJvdzEsIGNvbDEpIHRvCiAqIChyb3cyLCBjb2wyKSBpbmNsdXNpdmUuCiAqLwogICAgdm9pZApndWlfbWNoX2NsZWFyX2Jsb2NrKGludCByb3cxLCBpbnQgY29sMSwgaW50IHJvdzIsIGludCBjb2wyKQp7CiAgICBSZWN0IHJjOwoKICAgIC8qCiAgICAgKiBDbGVhciBvbmUgZXh0cmEgcGl4ZWwgYXQgdGhlIGZhciByaWdodCwgZm9yIHdoZW4gYm9sZCBjaGFyYWN0ZXJzIGhhdmUKICAgICAqIHNwaWxsZWQgb3ZlciB0byB0aGUgbmV4dCBjb2x1bW4uCiAgICAgKi8KICAgIHJjLmxlZnQgPSBGSUxMX1goY29sMSk7CiAgICByYy50b3AgPSBGSUxMX1kocm93MSk7CiAgICByYy5yaWdodCA9IEZJTExfWChjb2wyICsgMSkgKyAoY29sMiA9PSBDb2x1bW5zIC0gMSk7CiAgICByYy5ib3R0b20gPSBGSUxMX1kocm93MiArIDEpOwoKICAgIGd1aV9tY2hfc2V0X2JnX2NvbG9yKGd1aS5iYWNrX3BpeGVsKTsKICAgIEVyYXNlUmVjdCgmcmMpOwp9CgovKgogKiBDbGVhciB0aGUgd2hvbGUgdGV4dCB3aW5kb3cuCiAqLwogICAgdm9pZApndWlfbWNoX2NsZWFyX2FsbCh2b2lkKQp7CiAgICBSZWN0CXJjOwoKICAgIHJjLmxlZnQgPSAwOwogICAgcmMudG9wID0gMDsKICAgIHJjLnJpZ2h0ID0gQ29sdW1ucyAqIGd1aS5jaGFyX3dpZHRoICsgMiAqIGd1aS5ib3JkZXJfd2lkdGg7CiAgICByYy5ib3R0b20gPSBSb3dzICogZ3VpLmNoYXJfaGVpZ2h0ICsgMiAqIGd1aS5ib3JkZXJfd2lkdGg7CgogICAgZ3VpX21jaF9zZXRfYmdfY29sb3IoZ3VpLmJhY2tfcGl4ZWwpOwogICAgRXJhc2VSZWN0KCZyYyk7Ci8qICBndWlfbWNoX3NldF9mZ19jb2xvcihndWkubm9ybV9waXhlbCk7CiAgICBGcmFtZVJlY3QoJnJjKTsKKi8KfQoKLyoKICogRGVsZXRlIHRoZSBnaXZlbiBudW1iZXIgb2YgbGluZXMgZnJvbSB0aGUgZ2l2ZW4gcm93LCBzY3JvbGxpbmcgdXAgYW55CiAqIHRleHQgZnVydGhlciBkb3duIHdpdGhpbiB0aGUgc2Nyb2xsIHJlZ2lvbi4KICovCiAgICB2b2lkCmd1aV9tY2hfZGVsZXRlX2xpbmVzKGludCByb3csIGludCBudW1fbGluZXMpCnsKICAgIFJlY3QJcmM7CgogICAgLyogY2hhbmdlZCB3aXRob3V0IGNoZWNraW5nISAqLwogICAgcmMubGVmdCA9IEZJTExfWChndWkuc2Nyb2xsX3JlZ2lvbl9sZWZ0KTsKICAgIHJjLnJpZ2h0ID0gRklMTF9YKGd1aS5zY3JvbGxfcmVnaW9uX3JpZ2h0ICsgMSk7CiAgICByYy50b3AgPSBGSUxMX1kocm93KTsKICAgIHJjLmJvdHRvbSA9IEZJTExfWShndWkuc2Nyb2xsX3JlZ2lvbl9ib3QgKyAxKTsKCiAgICBndWlfbWNoX3NldF9iZ19jb2xvcihndWkuYmFja19waXhlbCk7CiAgICBTY3JvbGxSZWN0KCZyYywgMCwgLW51bV9saW5lcyAqIGd1aS5jaGFyX2hlaWdodCwgKFJnbkhhbmRsZSkgbmlsKTsKCiAgICBndWlfY2xlYXJfYmxvY2soZ3VpLnNjcm9sbF9yZWdpb25fYm90IC0gbnVtX2xpbmVzICsgMSwKCQkJCQkJICAgICAgIGd1aS5zY3JvbGxfcmVnaW9uX2xlZnQsCglndWkuc2Nyb2xsX3JlZ2lvbl9ib3QsIGd1aS5zY3JvbGxfcmVnaW9uX3JpZ2h0KTsKfQoKLyoKICogSW5zZXJ0IHRoZSBnaXZlbiBudW1iZXIgb2YgbGluZXMgYmVmb3JlIHRoZSBnaXZlbiByb3csIHNjcm9sbGluZyBkb3duIGFueQogKiBmb2xsb3dpbmcgdGV4dCB3aXRoaW4gdGhlIHNjcm9sbCByZWdpb24uCiAqLwogICAgdm9pZApndWlfbWNoX2luc2VydF9saW5lcyhpbnQgcm93LCBpbnQgbnVtX2xpbmVzKQp7CiAgICBSZWN0IHJjOwoKICAgIHJjLmxlZnQgPSBGSUxMX1goZ3VpLnNjcm9sbF9yZWdpb25fbGVmdCk7CiAgICByYy5yaWdodCA9IEZJTExfWChndWkuc2Nyb2xsX3JlZ2lvbl9yaWdodCArIDEpOwogICAgcmMudG9wID0gRklMTF9ZKHJvdyk7CiAgICByYy5ib3R0b20gPSBGSUxMX1koZ3VpLnNjcm9sbF9yZWdpb25fYm90ICsgMSk7CgogICAgZ3VpX21jaF9zZXRfYmdfY29sb3IoZ3VpLmJhY2tfcGl4ZWwpOwoKICAgIFNjcm9sbFJlY3QoJnJjLCAwLCBndWkuY2hhcl9oZWlnaHQgKiBudW1fbGluZXMsIChSZ25IYW5kbGUpIG5pbCk7CgogICAgLyogVXBkYXRlIGd1aS5jdXJzb3Jfcm93IGlmIHRoZSBjdXJzb3Igc2Nyb2xsZWQgb3IgY29waWVkIG92ZXIgKi8KICAgIGlmIChndWkuY3Vyc29yX3JvdyA+PSBndWkucm93CgkgICAgJiYgZ3VpLmN1cnNvcl9jb2wgPj0gZ3VpLnNjcm9sbF9yZWdpb25fbGVmdAoJICAgICYmIGd1aS5jdXJzb3JfY29sIDw9IGd1aS5zY3JvbGxfcmVnaW9uX3JpZ2h0KQogICAgewoJaWYgKGd1aS5jdXJzb3Jfcm93IDw9IGd1aS5zY3JvbGxfcmVnaW9uX2JvdCAtIG51bV9saW5lcykKCSAgICBndWkuY3Vyc29yX3JvdyArPSBudW1fbGluZXM7CgllbHNlIGlmIChndWkuY3Vyc29yX3JvdyA8PSBndWkuc2Nyb2xsX3JlZ2lvbl9ib3QpCgkgICAgZ3VpLmN1cnNvcl9pc192YWxpZCA9IEZBTFNFOwogICAgfQoKICAgIGd1aV9jbGVhcl9ibG9jayhyb3csIGd1aS5zY3JvbGxfcmVnaW9uX2xlZnQsCgkJCQlyb3cgKyBudW1fbGluZXMgLSAxLCBndWkuc2Nyb2xsX3JlZ2lvbl9yaWdodCk7Cn0KCiAgICAvKgogICAgICogVE9ETzogYWRkIGEgdmltIGZvcm1hdCB0byB0aGUgY2xpcGJvYXJkIHdoaWNoIHJlbWVtYmVyCiAgICAgKgkgICAgIExJTkVXSVNFLCBDSEFSV0lTRSwgQkxPQ0tXSVNFCiAgICAgKi8KCiAgICB2b2lkCmNsaXBfbWNoX3JlcXVlc3Rfc2VsZWN0aW9uKFZpbUNsaXBib2FyZCAqY2JkKQp7CgogICAgSGFuZGxlCXRleHRPZkNsaXA7CiAgICBpbnQJCWZsYXZvciA9IDA7CiAgICBTaXplCXNjcmFwU2l6ZTsKICAgIFNjcmFwRmxhdm9yRmxhZ3MJc2NyYXBGbGFnczsKICAgIFNjcmFwUmVmICAgIHNjcmFwID0gbmlsOwogICAgT1NTdGF0dXMJZXJyb3I7CiAgICBpbnQJCXR5cGU7CiAgICBjaGFyCSpzZWFyY2hDUjsKICAgIGNoYXJfdQkqdGVtcGNsaXA7CgoKICAgIGVycm9yID0gR2V0Q3VycmVudFNjcmFwKCZzY3JhcCk7CiAgICBpZiAoZXJyb3IgIT0gbm9FcnIpCglyZXR1cm47CgogICAgZXJyb3IgPSBHZXRTY3JhcEZsYXZvckZsYWdzKHNjcmFwLCBWSU1TQ1JBUEZMQVZPUiwgJnNjcmFwRmxhZ3MpOwogICAgaWYgKGVycm9yID09IG5vRXJyKQogICAgewoJZXJyb3IgPSBHZXRTY3JhcEZsYXZvclNpemUoc2NyYXAsIFZJTVNDUkFQRkxBVk9SLCAmc2NyYXBTaXplKTsKCWlmIChlcnJvciA9PSBub0VyciAmJiBzY3JhcFNpemUgPiAxKQoJICAgIGZsYXZvciA9IDE7CiAgICB9CgogICAgaWYgKGZsYXZvciA9PSAwKQogICAgewoJZXJyb3IgPSBHZXRTY3JhcEZsYXZvckZsYWdzKHNjcmFwLCBTQ1JBUFRFWFRGTEFWT1IsICZzY3JhcEZsYWdzKTsKCWlmIChlcnJvciAhPSBub0VycikKCSAgICByZXR1cm47CgoJZXJyb3IgPSBHZXRTY3JhcEZsYXZvclNpemUoc2NyYXAsIFNDUkFQVEVYVEZMQVZPUiwgJnNjcmFwU2l6ZSk7CglpZiAoZXJyb3IgIT0gbm9FcnIpCgkgICAgcmV0dXJuOwogICAgfQoKICAgIFJlc2VydmVNZW0oc2NyYXBTaXplKTsKCiAgICAvKiBJbiBDQVJCT04gd2UgZG9uJ3QgbmVlZCBhIEhhbmRsZSwgYSBwb2ludGVyIGlzIGdvb2QgKi8KICAgIHRleHRPZkNsaXAgPSBOZXdIYW5kbGUoc2NyYXBTaXplKTsKCiAgICAvKiB0ZW1wY2xpcCA9IGxhbGxvYyhzY3JhcFNpemUrMSwgVFJVRSk7ICovCiAgICBITG9jayh0ZXh0T2ZDbGlwKTsKICAgIGVycm9yID0gR2V0U2NyYXBGbGF2b3JEYXRhKHNjcmFwLAoJICAgIGZsYXZvciA/IFZJTVNDUkFQRkxBVk9SIDogU0NSQVBURVhURkxBVk9SLAoJICAgICZzY3JhcFNpemUsICp0ZXh0T2ZDbGlwKTsKICAgIHNjcmFwU2l6ZSAtPSBmbGF2b3I7CgogICAgaWYgKGZsYXZvcikKCXR5cGUgPSAqKnRleHRPZkNsaXA7CiAgICBlbHNlCgl0eXBlID0gKHN0cmNocigqdGV4dE9mQ2xpcCwgJ1xyJykgIT0gTlVMTCkgPyBNTElORSA6IE1DSEFSOwoKICAgIHRlbXBjbGlwID0gbGFsbG9jKHNjcmFwU2l6ZSArIDEsIFRSVUUpOwogICAgbWNoX21lbW1vdmUodGVtcGNsaXAsICp0ZXh0T2ZDbGlwICsgZmxhdm9yLCBzY3JhcFNpemUpOwogICAgdGVtcGNsaXBbc2NyYXBTaXplXSA9IDA7CgojaWZkZWYgTUFDT1NfQ09OVkVSVAogICAgewoJLyogQ29udmVydCBmcm9tIHV0Zi0xNiAoY2xpcGJvYXJkKSAqLwoJc2l6ZV90IGVuY0xlbiA9IDA7CgljaGFyX3UgKnRvID0gbWFjX3V0ZjE2X3RvX2VuYygoVW5pQ2hhciAqKXRlbXBjbGlwLCBzY3JhcFNpemUsICZlbmNMZW4pOwoKCWlmICh0byAhPSBOVUxMKQoJewoJICAgIHNjcmFwU2l6ZSA9IGVuY0xlbjsKCSAgICB2aW1fZnJlZSh0ZW1wY2xpcCk7CgkgICAgdGVtcGNsaXAgPSB0bzsKCX0KICAgIH0KI2VuZGlmCgogICAgc2VhcmNoQ1IgPSAoY2hhciAqKXRlbXBjbGlwOwogICAgd2hpbGUgKHNlYXJjaENSICE9IE5VTEwpCiAgICB7CglzZWFyY2hDUiA9IHN0cmNocihzZWFyY2hDUiwgJ1xyJyk7CglpZiAoc2VhcmNoQ1IgIT0gTlVMTCkKCSAgICAqc2VhcmNoQ1IgPSAnXG4nOwogICAgfQoKICAgIGNsaXBfeWFua19zZWxlY3Rpb24odHlwZSwgdGVtcGNsaXAsIHNjcmFwU2l6ZSwgY2JkKTsKCiAgICB2aW1fZnJlZSh0ZW1wY2xpcCk7CiAgICBIVW5sb2NrKHRleHRPZkNsaXApOwoKICAgIERpc3Bvc2VIYW5kbGUodGV4dE9mQ2xpcCk7Cn0KCiAgICB2b2lkCmNsaXBfbWNoX2xvc2Vfc2VsZWN0aW9uKFZpbUNsaXBib2FyZCAqY2JkKQp7CiAgICAvKgogICAgICogVE9ETzogUmVhbGx5IG5vdGhpbmcgdG8gZG8/CiAgICAgKi8KfQoKICAgIGludApjbGlwX21jaF9vd25fc2VsZWN0aW9uKFZpbUNsaXBib2FyZCAqY2JkKQp7CiAgICByZXR1cm4gT0s7Cn0KCi8qCiAqIFNlbmQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIHRvIHRoZSBjbGlwYm9hcmQuCiAqLwogICAgdm9pZApjbGlwX21jaF9zZXRfc2VsZWN0aW9uKFZpbUNsaXBib2FyZCAqY2JkKQp7CiAgICBIYW5kbGUJdGV4dE9mQ2xpcDsKICAgIGxvbmcJc2NyYXBTaXplOwogICAgaW50CQl0eXBlOwogICAgU2NyYXBSZWYgICAgc2NyYXA7CgogICAgY2hhcl91CSpzdHIgPSBOVUxMOwoKICAgIGlmICghY2JkLT5vd25lZCkKCXJldHVybjsKCiAgICBjbGlwX2dldF9zZWxlY3Rpb24oY2JkKTsKCiAgICAvKgogICAgICogT25jZSB3ZSBzZXQgdGhlIGNsaXBib2FyZCwgbG9zZSBvd25lcnNoaXAuICBJZiBhbm90aGVyIGFwcGxpY2F0aW9uIHNldHMKICAgICAqIHRoZSBjbGlwYm9hcmQsIHdlIGRvbid0IHdhbnQgdG8gdGhpbmsgdGhhdCB3ZSBzdGlsbCBvd24gaXQuCiAgICAgKi8KICAgIGNiZC0+b3duZWQgPSBGQUxTRTsKCiAgICB0eXBlID0gY2xpcF9jb252ZXJ0X3NlbGVjdGlvbigmc3RyLCAobG9uZ191ICopJnNjcmFwU2l6ZSwgY2JkKTsKCiNpZmRlZiBNQUNPU19DT05WRVJUCiAgICBzaXplX3QgdXRmMTZfbGVuID0gMDsKICAgIFVuaUNoYXIgKnRvID0gbWFjX2VuY190b191dGYxNihzdHIsIHNjcmFwU2l6ZSwgJnV0ZjE2X2xlbik7CiAgICBpZiAodG8pCiAgICB7CglzY3JhcFNpemUgPSB1dGYxNl9sZW47Cgl2aW1fZnJlZShzdHIpOwoJc3RyID0gKGNoYXJfdSAqKXRvOwogICAgfQojZW5kaWYKCiAgICBpZiAodHlwZSA+PSAwKQogICAgewoJQ2xlYXJDdXJyZW50U2NyYXAoKTsKCgl0ZXh0T2ZDbGlwID0gTmV3SGFuZGxlKHNjcmFwU2l6ZSArIDEpOwoJSExvY2sodGV4dE9mQ2xpcCk7CgoJKip0ZXh0T2ZDbGlwID0gdHlwZTsKCW1jaF9tZW1tb3ZlKCp0ZXh0T2ZDbGlwICsgMSwgc3RyLCBzY3JhcFNpemUpOwoJR2V0Q3VycmVudFNjcmFwKCZzY3JhcCk7CglQdXRTY3JhcEZsYXZvcihzY3JhcCwgU0NSQVBURVhURkxBVk9SLCBrU2NyYXBGbGF2b3JNYXNrTm9uZSwKCQlzY3JhcFNpemUsICp0ZXh0T2ZDbGlwICsgMSk7CglQdXRTY3JhcEZsYXZvcihzY3JhcCwgVklNU0NSQVBGTEFWT1IsIGtTY3JhcEZsYXZvck1hc2tOb25lLAoJCXNjcmFwU2l6ZSArIDEsICp0ZXh0T2ZDbGlwKTsKCUhVbmxvY2sodGV4dE9mQ2xpcCk7CglEaXNwb3NlSGFuZGxlKHRleHRPZkNsaXApOwogICAgfQoKICAgIHZpbV9mcmVlKHN0cik7Cn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0X3RleHRfYXJlYV9wb3MoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpCnsKICAgIFJlY3QJVmltQm91bmQ7CgovKiAgSGlkZVdpbmRvdyhndWkuVmltV2luZG93KTsgKi8KICAgIEdldFdpbmRvd0JvdW5kcyhndWkuVmltV2luZG93LCBrV2luZG93R2xvYmFsUG9ydFJnbiwgJlZpbUJvdW5kKTsKCiAgICBpZiAoZ3VpLndoaWNoX3Njcm9sbGJhcnNbU0JBUl9MRUZUXSkKICAgIHsKCVZpbUJvdW5kLmxlZnQgPSAtZ3VpLnNjcm9sbGJhcl93aWR0aCArIDE7CiAgICB9CiAgICBlbHNlCiAgICB7CglWaW1Cb3VuZC5sZWZ0ID0gMDsKICAgIH0KCiAgICBTZXRXaW5kb3dCb3VuZHMoZ3VpLlZpbVdpbmRvdywga1dpbmRvd0dsb2JhbFBvcnRSZ24sICZWaW1Cb3VuZCk7CgogICAgU2hvd1dpbmRvdyhndWkuVmltV2luZG93KTsKfQoKLyoKICogTWVudSBzdHVmZi4KICovCgogICAgdm9pZApndWlfbWNoX2VuYWJsZV9tZW51KGludCBmbGFnKQp7CiAgICAvKgogICAgICogTWVudSBpcyBhbHdheXMgYWN0aXZlLgogICAgICovCn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0X21lbnVfcG9zKGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKQp7CiAgICAvKgogICAgICogVGhlIG1lbnUgaXMgYWx3YXlzIGF0IHRoZSB0b3Agb2YgdGhlIHNjcmVlbi4KICAgICAqLwp9CgovKgogKiBBZGQgYSBzdWIgbWVudSB0byB0aGUgbWVudSBiYXIuCiAqLwogICAgdm9pZApndWlfbWNoX2FkZF9tZW51KHZpbW1lbnVfVCAqbWVudSwgaW50IGlkeCkKewogICAgLyoKICAgICAqIFRPRE86IFRyeSB0byB1c2Ugb25seSBtZW51X2lkIGluc3RlYWQgb2YgYm90aCBtZW51X2lkIGFuZCBtZW51X2hhbmRsZS4KICAgICAqIFRPRE86IHVzZSBtZW51LT5tbmVtb25pYyBhbmQgbWVudS0+YWN0ZXh0CiAgICAgKiBUT0RPOiBUcnkgdG8gcmV1c2UgbWVudSBpZAogICAgICogICAgICAgQ2FyYm9uIEhlbHAgc3VnZ2VzdCB0byB1c2Ugb25seSBpZCBiZXR3ZWVuIDEgYW5kIDIzNQogICAgICovCiAgICBzdGF0aWMgbG9uZwkgbmV4dF9hdmFpbF9pZCA9IDEyODsKICAgIGxvbmcJIG1lbnVfYWZ0ZXJfbWUgPSAwOyAvKiBEZWZhdWx0IHRvIHRoZSBlbmQgKi8KI2lmIGRlZmluZWQoRkVBVF9NQllURSkKICAgIENGU3RyaW5nUmVmIG5hbWU7CiNlbHNlCiAgICBjaGFyX3UJKm5hbWU7CiNlbmRpZgogICAgc2hvcnQJIGluZGV4OwogICAgdmltbWVudV9UCSpwYXJlbnQgPSBtZW51LT5wYXJlbnQ7CiAgICB2aW1tZW51X1QJKmJyb3RoZXIgPSBtZW51LT5uZXh0OwoKICAgIC8qIENhbm5vdCBhZGQgYSBtZW51IGlmIC4uLiAqLwogICAgaWYgKChwYXJlbnQgIT0gTlVMTCAmJiBwYXJlbnQtPnN1Ym1lbnVfaWQgPT0gMCkpCglyZXR1cm47CgogICAgLyogbWVudSBJRCBncmVhdGVyIHRoYW4gMTAyNCBhcmUgcmVzZXJ2ZWQgZm9yID8/PyAqLwogICAgaWYgKG5leHRfYXZhaWxfaWQgPT0gMTAyNCkKCXJldHVybjsKCiAgICAvKiBNeSBicm90aGVyIGNvdWxkIGJlIHRoZSBQb3BVcCwgZmluZCBteSByZWFsIGJyb3RoZXIgKi8KICAgIHdoaWxlICgoYnJvdGhlciAhPSBOVUxMKSAmJiAoIW1lbnVfaXNfbWVudWJhcihicm90aGVyLT5uYW1lKSkpCglicm90aGVyID0gYnJvdGhlci0+bmV4dDsKCiAgICAvKiAgRmluZCB3aGVyZSB0byBpbnNlcnQgdGhlIG1lbnUgKGZvciBNZW51QmFyKSAqLwogICAgaWYgKChwYXJlbnQgPT0gTlVMTCkgJiYgKGJyb3RoZXIgIT0gTlVMTCkpCgltZW51X2FmdGVyX21lID0gYnJvdGhlci0+c3VibWVudV9pZDsKCiAgICAvKiBJZiB0aGUgbWVudSBpcyBub3QgcGFydCBvZiB0aGUgbWVudWJhciAoYW5kIGl0cyBzdWJtZW51cyksIGFkZCBpdCAnbm93aGVyZScgKi8KICAgIGlmICghbWVudV9pc19tZW51YmFyKG1lbnUtPm5hbWUpKQoJbWVudV9hZnRlcl9tZSA9IGhpZXJNZW51OwoKICAgIC8qIENvbnZlcnQgdGhlIG5hbWUgKi8KI2lmZGVmIE1BQ09TX0NPTlZFUlQKICAgIG5hbWUgPSBtZW51X3RpdGxlX3JlbW92aW5nX21uZW1vbmljKG1lbnUpOwojZWxzZQogICAgbmFtZSA9IEMyUGFzY2FsX3NhdmUobWVudS0+ZG5hbWUpOwojZW5kaWYKICAgIGlmIChuYW1lID09IE5VTEwpCglyZXR1cm47CgogICAgLyogQ3JlYXRlIHRoZSBtZW51IHVubGVzcyBpdCdzIHRoZSBoZWxwIG1lbnUgKi8KICAgIHsKCS8qIENhcmJvbiBzdWdnZXN0IHVzZSBvZgoJICogT1NTdGF0dXMgQ3JlYXRlTmV3TWVudShNZW51SUQsIE1lbnVBdHRyaWJ1dGVzLCBNZW51UmVmICopOwoJICogT1NTdGF0dXMgU2V0TWVudVRpdGxlKE1lbnVSZWYsIENvbnN0U3RyMjU1UGFyYW0gdGl0bGUpOwoJICovCgltZW51LT5zdWJtZW51X2lkID0gbmV4dF9hdmFpbF9pZDsKI2lmIGRlZmluZWQoRkVBVF9NQllURSkKCWlmIChDcmVhdGVOZXdNZW51KG1lbnUtPnN1Ym1lbnVfaWQsIDAsIChNZW51UmVmICopJm1lbnUtPnN1Ym1lbnVfaGFuZGxlKSA9PSBub0VycikKCSAgICBTZXRNZW51VGl0bGVXaXRoQ0ZTdHJpbmcoKE1lbnVSZWYpbWVudS0+c3VibWVudV9oYW5kbGUsIG5hbWUpOwojZWxzZQoJbWVudS0+c3VibWVudV9oYW5kbGUgPSBOZXdNZW51KG1lbnUtPnN1Ym1lbnVfaWQsIG5hbWUpOwojZW5kaWYKCW5leHRfYXZhaWxfaWQrKzsKICAgIH0KCiAgICBpZiAocGFyZW50ID09IE5VTEwpCiAgICB7CgkvKiBBZGRpbmcgYSBtZW51IHRvIHRoZSBtZW51YmFyLCBvciBpbiB0aGUgbm8gbWFucyBsYW5kIChmb3IgUG9wVXApICovCgoJLyogVE9ETzogVmVyaWZ5IGlmIHdlIGNvdWxkIG9ubHkgSW5zZXJ0IE1lbnUgaWYgcmVhbGx5IHBhcnQgb2YgdGhlCgkgKiBtZW51YmFyIFRoZSBJbnNlcnRlZCBtZW51IGFyZSBzY2FubmVkIG9yIHRoZSBDb21tYW5kLWtleSBjb21ib3MKCSAqLwoKCS8qIEluc2VydCB0aGUgbWVudSAqLwoJSW5zZXJ0TWVudShtZW51LT5zdWJtZW51X2hhbmRsZSwgbWVudV9hZnRlcl9tZSk7IC8qIGluc2VydCBiZWZvcmUgKi8KI2lmIDEKCS8qIFZpbSBzaG91bGQgbm9ybWFsbHkgdXBkYXRlIGl0LiBUT0RPOiB2ZXJpZnkgKi8KCURyYXdNZW51QmFyKCk7CiNlbmRpZgogICAgfQogICAgZWxzZQogICAgewoJLyogQWRkaW5nIGFzIGEgc3VibWVudSAqLwoKCWluZGV4ID0gZ3VpX21hY19nZXRfbWVudV9pdGVtX2luZGV4KG1lbnUpOwoKCS8qIENhbGwgSW5zZXJ0TWVudUl0ZW0gZm9sbG93ZWQgYnkgU2V0TWVudUl0ZW1UZXh0CgkgKiB0byBhdm9pZCBzcGVjaWFsIGNoYXJhY3RlciByZWNvZ25pdGlvbiBieSBJbnNlcnRNZW51SXRlbQoJICovCglJbnNlcnRNZW51SXRlbShwYXJlbnQtPnN1Ym1lbnVfaGFuZGxlLCAiXHAgIiwgaWR4KTsgLyogYWZ0ZXJJdGVtICovCiNpZiBkZWZpbmVkKEZFQVRfTUJZVEUpCglTZXRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcocGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaWR4KzEsIG5hbWUpOwojZWxzZQoJU2V0TWVudUl0ZW1UZXh0KHBhcmVudC0+c3VibWVudV9oYW5kbGUsIGlkeCsxLCBuYW1lKTsKI2VuZGlmCglTZXRJdGVtQ21kKHBhcmVudC0+c3VibWVudV9oYW5kbGUsIGlkeCsxLCAweDFCKTsKCVNldEl0ZW1NYXJrKHBhcmVudC0+c3VibWVudV9oYW5kbGUsIGlkeCsxLCBtZW51LT5zdWJtZW51X2lkKTsKCUluc2VydE1lbnUobWVudS0+c3VibWVudV9oYW5kbGUsIGhpZXJNZW51KTsKICAgIH0KCiNpZiBkZWZpbmVkKEZFQVRfTUJZVEUpCiAgICBDRlJlbGVhc2UobmFtZSk7CiNlbHNlCiAgICB2aW1fZnJlZShuYW1lKTsKI2VuZGlmCgojaWYgMAogICAgLyogRG9uZSBieSBWaW0gbGF0ZXIgb24gKi8KICAgIERyYXdNZW51QmFyKCk7CiNlbmRpZgp9CgovKgogKiBBZGQgYSBtZW51IGl0ZW0gdG8gYSBtZW51CiAqLwogICAgdm9pZApndWlfbWNoX2FkZF9tZW51X2l0ZW0odmltbWVudV9UICptZW51LCBpbnQgaWR4KQp7CiNpZiBkZWZpbmVkKEZFQVRfTUJZVEUpCiAgICBDRlN0cmluZ1JlZiBuYW1lOwojZWxzZQogICAgY2hhcl91CSpuYW1lOwojZW5kaWYKICAgIHZpbW1lbnVfVAkqcGFyZW50ID0gbWVudS0+cGFyZW50OwogICAgaW50CQltZW51X2luc2VydGVkOwoKICAgIC8qIENhbm5vdCBhZGQgaXRlbSwgaWYgdGhlIG1lbnUgaGF2ZSBub3QgYmVlbiBjcmVhdGVkICovCiAgICBpZiAocGFyZW50LT5zdWJtZW51X2lkID09IDApCglyZXR1cm47CgogICAgLyogQ291bGQgY2FsbCBTZXRNZW51UmVmQ29uIFtDQVJCT05dIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBNZW51LAogICAgICAgZm9yIG9sZGVyIE9TIGNhbGwgR2V0TWVudUl0ZW1EYXRhIChtZW51LCBpdGVtLCBpc0NvbW1hbmRJRD8sIGRhdGEpICovCgogICAgLyogQ29udmVydCB0aGUgbmFtZSAqLwojaWZkZWYgTUFDT1NfQ09OVkVSVAogICAgbmFtZSA9IG1lbnVfdGl0bGVfcmVtb3ZpbmdfbW5lbW9uaWMobWVudSk7CiNlbHNlCiAgICBuYW1lID0gQzJQYXNjYWxfc2F2ZShtZW51LT5kbmFtZSk7CiNlbmRpZgoKICAgIC8qIFdoZXJlIGFyZSBqdXN0IGEgbWVudSBpdGVtLCBzbyBubyBoYW5kbGUsIG5vIGlkICovCiAgICBtZW51LT5zdWJtZW51X2lkID0gMDsKICAgIG1lbnUtPnN1Ym1lbnVfaGFuZGxlID0gTlVMTDsKCiAgICBtZW51X2luc2VydGVkID0gMDsKICAgIGlmIChtZW51LT5hY3RleHQpCiAgICB7CgkvKiBJZiB0aGUgYWNjZWxlcmF0b3IgdGV4dCBmb3IgdGhlIG1lbnUgaXRlbSBsb29rcyBsaWtlIGl0IGRlc2NyaWJlcwoJICogYSBjb21tYW5kIGtleSAoZS5nLiwgIjxELVMtdD4iIG9yICI8Qy03PiIpLCBkaXNwbGF5IGl0IGFzIHRoZQoJICogaXRlbSdzIGNvbW1hbmQgZXF1aXZhbGVudC4KCSAqLwoJaW50CSAgICBrZXkgPSAwOwoJaW50CSAgICBtb2RpZmllcnMgPSAwOwoJY2hhcl91CSAgICAqcF9hY3RleHQ7CgoJcF9hY3RleHQgPSBtZW51LT5hY3RleHQ7CglrZXkgPSBmaW5kX3NwZWNpYWxfa2V5KCZwX2FjdGV4dCwgJm1vZGlmaWVycywgLyprZXljb2RlPSovMCk7CglpZiAoKnBfYWN0ZXh0ICE9IDApCgkgICAga2V5ID0gMDsgLyogZXJyb3I6IHRyYWlsaW5nIHRleHQgKi8KCS8qIGZpbmRfc3BlY2lhbF9rZXkoKSByZXR1cm5zIGEga2V5Y29kZSB3aXRoIGFzIG1hbnkgb2YgdGhlCgkgKiBzcGVjaWZpZWQgbW9kaWZpZXJzIGFzIGFwcHJvcHJpYXRlIGFscmVhZHkgYXBwbGllZCAoZS5nLiwgZm9yCgkgKiAiPEQtQy14PiIgaXQgcmV0dXJucyBDdHJsLVggYXMgdGhlIGtleWNvZGUgYW5kIE1PRF9NQVNLX0NNRAoJICogYXMgdGhlIG9ubHkgbW9kaWZpZXIpLiAgU2luY2Ugd2Ugd2FudCB0byBkaXNwbGF5IGFsbCBvZiB0aGUKCSAqIG1vZGlmaWVycywgd2UgbmVlZCB0byBjb252ZXJ0IHRoZSBrZXljb2RlIGJhY2sgdG8gYSBwcmludGFibGUKCSAqIGNoYXJhY3RlciBwbHVzIG1vZGlmaWVycy4KCSAqIFRPRE86IFdyaXRlIGFuIGFsdGVybmF0aXZlIGZpbmRfc3BlY2lhbF9rZXkoKSB0aGF0IGRvZXNuJ3QKCSAqIGFwcGx5IG1vZGlmaWVycy4KCSAqLwoJaWYgKGtleSA+IDAgJiYga2V5IDwgMzIpCgl7CgkgICAgLyogQ29udmVydCBhIGNvbnRyb2wga2V5IHRvIGFuIHVwcGVyY2FzZSBsZXR0ZXIuICBOb3RlIHRoYXQKCSAgICAgKiBieSB0aGlzIHBvaW50IGl0IGlzIG5vIGxvbmdlciBwb3NzaWJsZSB0byBkaXN0aW5ndWlzaAoJICAgICAqIGJldHdlZW4sIGUuZy4sIEN0cmwtUyBhbmQgQ3RybC1TaGlmdC1TLgoJICAgICAqLwoJICAgIG1vZGlmaWVycyB8PSBNT0RfTUFTS19DVFJMOwoJICAgIGtleSArPSAnQCc7Cgl9CgkvKiBJZiB0aGUga2V5Y29kZSBpcyBhbiB1cHBlcmNhc2UgbGV0dGVyLCBzZXQgdGhlIFNoaWZ0IG1vZGlmaWVyLgoJICogSWYgaXQgaXMgYSBsb3dlcmNhc2UgbGV0dGVyLCBkb24ndCBzZXQgdGhlIG1vZGlmaWVyLCBidXQgY29udmVydAoJICogdGhlIGxldHRlciB0byB1cHBlcmNhc2UgZm9yIGRpc3BsYXkgaW4gdGhlIG1lbnUuCgkgKi8KCWVsc2UgaWYgKGtleSA+PSAnQScgJiYga2V5IDw9ICdaJykKCSAgICBtb2RpZmllcnMgfD0gTU9EX01BU0tfU0hJRlQ7CgllbHNlIGlmIChrZXkgPj0gJ2EnICYmIGtleSA8PSAneicpCgkgICAga2V5ICs9ICdBJyAtICdhJzsKCS8qIE5vdGU6IGtleWNvZGVzIGJlbG93IDB4MjIgYXJlIHJlc2VydmVkIGJ5IEFwcGxlLiAqLwoJaWYgKGtleSA+PSAweDIyICYmIHZpbV9pc3ByaW50Y19zdHJpY3Qoa2V5KSkKCXsKCSAgICBpbnQJCXZhbGlkID0gMTsKCSAgICBjaGFyX3UgICAgICBtYWNfbW9kcyA9IGtNZW51Tm9Nb2RpZmllcnM7CgkgICAgLyogQ29udmVydCBWaW0gbW9kaWZpZXIgY29kZXMgdG8gTWVudSBNYW5hZ2VyIGVxdWl2YWxlbnRzLiAqLwoJICAgIGlmIChtb2RpZmllcnMgJiBNT0RfTUFTS19TSElGVCkKCQltYWNfbW9kcyB8PSBrTWVudVNoaWZ0TW9kaWZpZXI7CgkgICAgaWYgKG1vZGlmaWVycyAmIE1PRF9NQVNLX0NUUkwpCgkJbWFjX21vZHMgfD0ga01lbnVDb250cm9sTW9kaWZpZXI7CgkgICAgaWYgKCEobW9kaWZpZXJzICYgTU9EX01BU0tfQ01EKSkKCQltYWNfbW9kcyB8PSBrTWVudU5vQ29tbWFuZE1vZGlmaWVyOwoJICAgIGlmIChtb2RpZmllcnMgJiBNT0RfTUFTS19BTFQgfHwgbW9kaWZpZXJzICYgTU9EX01BU0tfTVVMVElfQ0xJQ0spCgkJdmFsaWQgPSAwOyAvKiBUT0RPOiB3aWxsIEFsdCBzb21lZGF5IG1hcCB0byBPcHRpb24/ICovCgkgICAgaWYgKHZhbGlkKQoJICAgIHsKCQljaGFyX3UJICAgIGl0ZW1fdHh0WzEwXTsKCQkvKiBJbnNlcnQgdGhlIG1lbnUgaXRlbSBhZnRlciBpZHgsIHdpdGggaXRzIGNvbW1hbmQga2V5LiAqLwoJCWl0ZW1fdHh0WzBdID0gMzsgaXRlbV90eHRbMV0gPSAnICc7IGl0ZW1fdHh0WzJdID0gJy8nOwoJCWl0ZW1fdHh0WzNdID0ga2V5OwoJCUluc2VydE1lbnVJdGVtKHBhcmVudC0+c3VibWVudV9oYW5kbGUsIGl0ZW1fdHh0LCBpZHgpOwoJCS8qIFNldCB0aGUgbW9kaWZpZXIga2V5cy4gKi8KCQlTZXRNZW51SXRlbU1vZGlmaWVycyhwYXJlbnQtPnN1Ym1lbnVfaGFuZGxlLCBpZHgrMSwgbWFjX21vZHMpOwoJCW1lbnVfaW5zZXJ0ZWQgPSAxOwoJICAgIH0KCX0KICAgIH0KICAgIC8qIENhbGwgSW5zZXJ0TWVudUl0ZW0gZm9sbG93ZWQgYnkgU2V0TWVudUl0ZW1UZXh0CiAgICAgKiB0byBhdm9pZCBzcGVjaWFsIGNoYXJhY3RlciByZWNvZ25pdGlvbiBieSBJbnNlcnRNZW51SXRlbQogICAgICovCiAgICBpZiAoIW1lbnVfaW5zZXJ0ZWQpCglJbnNlcnRNZW51SXRlbShwYXJlbnQtPnN1Ym1lbnVfaGFuZGxlLCAiXHAgIiwgaWR4KTsgLyogYWZ0ZXJJdGVtICovCiAgICAvKiBTZXQgdGhlIG1lbnUgaXRlbSBuYW1lLiAqLwojaWYgZGVmaW5lZChGRUFUX01CWVRFKQogICAgU2V0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nKHBhcmVudC0+c3VibWVudV9oYW5kbGUsIGlkeCsxLCBuYW1lKTsKI2Vsc2UKICAgIFNldE1lbnVJdGVtVGV4dChwYXJlbnQtPnN1Ym1lbnVfaGFuZGxlLCBpZHgrMSwgbmFtZSk7CiNlbmRpZgoKI2lmIDAKICAgIC8qIENhbGxlZCBieSBWaW0gKi8KICAgIERyYXdNZW51QmFyKCk7CiNlbmRpZgoKI2lmIGRlZmluZWQoRkVBVF9NQllURSkKICAgIENGUmVsZWFzZShuYW1lKTsKI2Vsc2UKICAgIC8qIFRPRE86IENhbiBuYW1lIGJlIGZyZWVkPyAqLwogICAgdmltX2ZyZWUobmFtZSk7CiNlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX3RvZ2dsZV90ZWFyb2ZmcyhpbnQgZW5hYmxlKQp7CiAgICAvKiBubyB0ZWFyb2ZmIG1lbnVzICovCn0KCi8qCiAqIERlc3Ryb3kgdGhlIG1hY2hpbmUgc3BlY2lmaWMgbWVudSB3aWRnZXQuCiAqLwogICAgdm9pZApndWlfbWNoX2Rlc3Ryb3lfbWVudSh2aW1tZW51X1QgKm1lbnUpCnsKICAgIHNob3J0CWluZGV4ID0gZ3VpX21hY19nZXRfbWVudV9pdGVtX2luZGV4KG1lbnUpOwoKICAgIGlmIChpbmRleCA+IDApCiAgICB7CiAgICAgIGlmIChtZW51LT5wYXJlbnQpCiAgICAgIHsKCXsKCSAgICAvKiBGb3Igbm93IGp1c3QgZG9uJ3QgZGVsZXRlIGhlbHAgbWVudSBpdGVtcy4gKEh1aD8gRGFueSkgKi8KCSAgICBEZWxldGVNZW51SXRlbShtZW51LT5wYXJlbnQtPnN1Ym1lbnVfaGFuZGxlLCBpbmRleCk7CgoJICAgIC8qIERlbGV0ZSB0aGUgTWVudSBpZiBpdCB3YXMgYSBoaWVyYXJjaGljYWwgTWVudSAqLwoJICAgIGlmIChtZW51LT5zdWJtZW51X2lkICE9IDApCgkgICAgewoJCURlbGV0ZU1lbnUobWVudS0+c3VibWVudV9pZCk7CgkJRGlzcG9zZU1lbnUobWVudS0+c3VibWVudV9oYW5kbGUpOwoJICAgIH0KCX0KICAgICAgfQojaWZkZWYgREVCVUdfTUFDX01FTlUKICAgICAgZWxzZQogICAgICB7CglwcmludGYoImdtZG0gMlxuIik7CiAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBlbHNlCiAgICB7Cgl7CgkgICAgRGVsZXRlTWVudShtZW51LT5zdWJtZW51X2lkKTsKCSAgICBEaXNwb3NlTWVudShtZW51LT5zdWJtZW51X2hhbmRsZSk7Cgl9CiAgICB9CiAgICAvKiBTaG91bGRuJ3QgdGhpcyBiZSBhbHJlYWR5IGRvbmUgYnkgVmltLiBUT0RPOiBDaGVjayAqLwogICAgRHJhd01lbnVCYXIoKTsKfQoKLyoKICogTWFrZSBhIG1lbnUgZWl0aGVyIGdyZXkgb3Igbm90IGdyZXkuCiAqLwogICAgdm9pZApndWlfbWNoX21lbnVfZ3JleSh2aW1tZW51X1QgKm1lbnUsIGludCBncmV5KQp7CiAgICAvKiBUT0RPOiBDaGVjayBpZiBtZW51IHJlYWxseSBleGlzdHMgKi8KICAgIHNob3J0IGluZGV4ID0gZ3VpX21hY19nZXRfbWVudV9pdGVtX2luZGV4KG1lbnUpOwovKgogICAgaW5kZXggPSBtZW51LT5pbmRleDsKKi8KICAgIGlmIChncmV5KQogICAgewoJaWYgKG1lbnUtPmNoaWxkcmVuKQoJICAgIERpc2FibGVNZW51SXRlbShtZW51LT5zdWJtZW51X2hhbmRsZSwgaW5kZXgpOwoJaWYgKG1lbnUtPnBhcmVudCkKCSAgaWYgKG1lbnUtPnBhcmVudC0+c3VibWVudV9oYW5kbGUpCgkgICAgRGlzYWJsZU1lbnVJdGVtKG1lbnUtPnBhcmVudC0+c3VibWVudV9oYW5kbGUsIGluZGV4KTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChtZW51LT5jaGlsZHJlbikKCSAgICBFbmFibGVNZW51SXRlbShtZW51LT5zdWJtZW51X2hhbmRsZSwgaW5kZXgpOwoJaWYgKG1lbnUtPnBhcmVudCkKCSAgaWYgKG1lbnUtPnBhcmVudC0+c3VibWVudV9oYW5kbGUpCgkgICAgRW5hYmxlTWVudUl0ZW0obWVudS0+cGFyZW50LT5zdWJtZW51X2hhbmRsZSwgaW5kZXgpOwogICAgfQp9CgovKgogKiBNYWtlIG1lbnUgaXRlbSBoaWRkZW4gb3Igbm90IGhpZGRlbgogKi8KICAgIHZvaWQKZ3VpX21jaF9tZW51X2hpZGRlbih2aW1tZW51X1QgKm1lbnUsIGludCBoaWRkZW4pCnsKICAgIC8qIFRoZXJlJ3Mgbm8gaGlkZGVuIG1vZGUgb24gTWFjT1MgKi8KICAgIGd1aV9tY2hfbWVudV9ncmV5KG1lbnUsIGhpZGRlbik7Cn0KCgovKgogKiBUaGlzIGlzIGNhbGxlZCBhZnRlciBzZXR0aW5nIGFsbCB0aGUgbWVudXMgdG8gZ3JleS9oaWRkZW4gb3Igbm90LgogKi8KICAgIHZvaWQKZ3VpX21jaF9kcmF3X21lbnViYXIodm9pZCkKewogICAgRHJhd01lbnVCYXIoKTsKfQoKCi8qCiAqIFNjcm9sbGJhciBzdHVmZi4KICovCgogICAgdm9pZApndWlfbWNoX2VuYWJsZV9zY3JvbGxiYXIoCglzY3JvbGxiYXJfVAkqc2IsCglpbnQJCWZsYWcpCnsKICAgIGlmIChmbGFnKQoJU2hvd0NvbnRyb2woc2ItPmlkKTsKICAgIGVsc2UKCUhpZGVDb250cm9sKHNiLT5pZCk7CgojaWZkZWYgREVCVUdfTUFDX1NCCiAgICBwcmludGYoImVuYl9zYiAoJXgpICV4XG4iLHNiLT5pZCwgZmxhZyk7CiNlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX3NldF9zY3JvbGxiYXJfdGh1bWIoCglzY3JvbGxiYXJfVCAqc2IsCglsb25nIHZhbCwKCWxvbmcgc2l6ZSwKCWxvbmcgbWF4KQp7CiAgICBTZXRDb250cm9sMzJCaXRNYXhpbXVtIChzYi0+aWQsIG1heCk7CiAgICBTZXRDb250cm9sMzJCaXRNaW5pbXVtIChzYi0+aWQsIDApOwogICAgU2V0Q29udHJvbDMyQml0VmFsdWUgICAoc2ItPmlkLCB2YWwpOwojaWZkZWYgREVCVUdfTUFDX1NCCiAgICBwcmludGYoInRodW1iX3NiICgleCkgJXgsICV4LCV4XG4iLHNiLT5pZCwgdmFsLCBzaXplLCBtYXgpOwojZW5kaWYKfQoKICAgIHZvaWQKZ3VpX21jaF9zZXRfc2Nyb2xsYmFyX3BvcygKCXNjcm9sbGJhcl9UICpzYiwKCWludCB4LAoJaW50IHksCglpbnQgdywKCWludCBoKQp7CiAgICBndWlfbWNoX3NldF9iZ19jb2xvcihndWkuYmFja19waXhlbCk7Ci8qICBpZiAoZ3VpLndoaWNoX3Njcm9sbGJhcnNbU0JBUl9MRUZUXSkKICAgIHsKCU1vdmVDb250cm9sKHNiLT5pZCwgeC0xNiwgeSk7CglTaXplQ29udHJvbChzYi0+aWQsIHcgKyAxLCBoKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCU1vdmVDb250cm9sKHNiLT5pZCwgeCwgeSk7CglTaXplQ29udHJvbChzYi0+aWQsIHcgKyAxLCBoKTsKICAgIH0qLwogICAgaWYgKHNiID09ICZndWkuYm90dG9tX3NiYXIpCgloICs9IDE7CiAgICBlbHNlCgl3ICs9IDE7CgogICAgaWYgKGd1aS53aGljaF9zY3JvbGxiYXJzW1NCQVJfTEVGVF0pCgl4IC09IDE1OwoKICAgIE1vdmVDb250cm9sKHNiLT5pZCwgeCwgeSk7CiAgICBTaXplQ29udHJvbChzYi0+aWQsIHcsIGgpOwojaWZkZWYgREVCVUdfTUFDX1NCCiAgICBwcmludGYoInNpemVfc2IgKCV4KSAleCwgJXgsICV4LCAleFxuIixzYi0+aWQsIHgsIHksIHcsIGgpOwojZW5kaWYKfQoKICAgIHZvaWQKZ3VpX21jaF9jcmVhdGVfc2Nyb2xsYmFyKAoJc2Nyb2xsYmFyX1QgKnNiLAoJaW50IG9yaWVudCkJLyogU0JBUl9WRVJUIG9yIFNCQVJfSE9SSVogKi8KewogICAgUmVjdCBib3VuZHM7CgogICAgYm91bmRzLnRvcCA9IC0xNjsKICAgIGJvdW5kcy5ib3R0b20gPSAtMTA7CiAgICBib3VuZHMucmlnaHQgPSAtMTA7CiAgICBib3VuZHMubGVmdCA9IC0xNjsKCiAgICBzYi0+aWQgPSBOZXdDb250cm9sKGd1aS5WaW1XaW5kb3csCgkJCSAmYm91bmRzLAoJCQkgIlxwU2Nyb2xsQmFyIiwKCQkJIFRSVUUsCgkJCSAwLCAvKiBjdXJyZW50Ki8KCQkJIDAsIC8qIHRvcCAqLwoJCQkgMCwgLyogYm90dG9tICovCgkJCSBrQ29udHJvbFNjcm9sbEJhckxpdmVQcm9jLAoJCQkgKGxvbmcpIHNiLT5pZGVudCk7CiNpZmRlZiBERUJVR19NQUNfU0IKICAgIHByaW50ZigiY3JlYXRlX3NiICgleCkgJXhcbiIsc2ItPmlkLCBvcmllbnQpOwojZW5kaWYKfQoKICAgIHZvaWQKZ3VpX21jaF9kZXN0cm95X3Njcm9sbGJhcihzY3JvbGxiYXJfVCAqc2IpCnsKICAgIGd1aV9tY2hfc2V0X2JnX2NvbG9yKGd1aS5iYWNrX3BpeGVsKTsKICAgIERpc3Bvc2VDb250cm9sKHNiLT5pZCk7CiNpZmRlZiBERUJVR19NQUNfU0IKICAgIHByaW50ZigiZGVzdF9zYiAoJXgpIFxuIixzYi0+aWQpOwojZW5kaWYKfQoKCi8qCiAqIEN1cnNvciBibGluayBmdW5jdGlvbnMuCiAqCiAqIFRoaXMgaXMgYSBzaW1wbGUgc3RhdGUgbWFjaGluZToKICogQkxJTktfTk9ORQlub3QgYmxpbmtpbmcgYXQgYWxsCiAqIEJMSU5LX09GRglibGlua2luZywgY3Vyc29yIGlzIG5vdCBzaG93bgogKiBCTElOS19PTiBibGlua2luZywgY3Vyc29yIGlzIHNob3duCiAqLwogICAgdm9pZApndWlfbWNoX3NldF9ibGlua2luZyhsb25nIHdhaXQsIGxvbmcgb24sIGxvbmcgb2ZmKQp7CiAgICAvKiBUT0RPOiBUT0RPOiBUT0RPOiBUT0RPOiAqLwovKiAgICBibGlua193YWl0dGltZSA9IHdhaXQ7CiAgICBibGlua19vbnRpbWUgPSBvbjsKICAgIGJsaW5rX29mZnRpbWUgPSBvZmY7Ki8KfQoKLyoKICogU3RvcCB0aGUgY3Vyc29yIGJsaW5raW5nLiAgU2hvdyB0aGUgY3Vyc29yIGlmIGl0IHdhc24ndCBzaG93bi4KICovCiAgICB2b2lkCmd1aV9tY2hfc3RvcF9ibGluayh2b2lkKQp7CiAgICBndWlfdXBkYXRlX2N1cnNvcihUUlVFLCBGQUxTRSk7CiAgICAvKiBUT0RPOiBUT0RPOiBUT0RPOiBUT0RPOiAqLwovKiAgICBndWlfdzMyX3JtX2JsaW5rX3RpbWVyKCk7CiAgICBpZiAoYmxpbmtfc3RhdGUgPT0gQkxJTktfT0ZGKQogICAgZ3VpX3VwZGF0ZV9jdXJzb3IoVFJVRSwgRkFMU0UpOwogICAgYmxpbmtfc3RhdGUgPSBCTElOS19OT05FOyovCn0KCi8qCiAqIFN0YXJ0IHRoZSBjdXJzb3IgYmxpbmtpbmcuICBJZiBpdCB3YXMgYWxyZWFkeSBibGlua2luZywgdGhpcyByZXN0YXJ0cyB0aGUKICogd2FpdGluZyB0aW1lIGFuZCBzaG93cyB0aGUgY3Vyc29yLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zdGFydF9ibGluayh2b2lkKQp7CiAgICBndWlfdXBkYXRlX2N1cnNvcihUUlVFLCBGQUxTRSk7CiAgICAvKiBUT0RPOiBUT0RPOiBUT0RPOiBUT0RPOiAqLwovKiAgICBndWlfdzMyX3JtX2JsaW5rX3RpbWVyKCk7ICovCgogICAgLyogT25seSBzd2l0Y2ggYmxpbmtpbmcgb24gaWYgbm9uZSBvZiB0aGUgdGltZXMgaXMgemVybyAqLwovKiAgICBpZiAoYmxpbmtfd2FpdHRpbWUgJiYgYmxpbmtfb250aW1lICYmIGJsaW5rX29mZnRpbWUpCiAgICB7CiAgICBibGlua190aW1lciA9IFNldFRpbWVyKE5VTEwsIDAsIChVSU5UKWJsaW5rX3dhaXR0aW1lLAoJCQkgICAgKFRJTUVSUFJPQylfT25CbGlua1RpbWVyKTsKICAgIGJsaW5rX3N0YXRlID0gQkxJTktfT047CiAgICBndWlfdXBkYXRlX2N1cnNvcihUUlVFLCBGQUxTRSk7CiAgICB9Ki8KfQoKLyoKICogUmV0dXJuIHRoZSBSR0IgdmFsdWUgb2YgYSBwaXhlbCBhcyBsb25nLgogKi8KICAgIGxvbmdfdQpndWlfbWNoX2dldF9yZ2IoZ3VpY29sb3JfVCBwaXhlbCkKewogICAgcmV0dXJuIChSZWQocGl4ZWwpIDw8IDE2KSArIChHcmVlbihwaXhlbCkgPDwgOCkgKyBCbHVlKHBpeGVsKTsKfQoKCgojaWZkZWYgRkVBVF9CUk9XU0UKLyoKICogUG9wIG9wZW4gYSBmaWxlIGJyb3dzZXIgYW5kIHJldHVybiB0aGUgZmlsZSBzZWxlY3RlZCwgaW4gYWxsb2NhdGVkIG1lbW9yeSwKICogb3IgTlVMTCBpZiBDYW5jZWwgaXMgaGl0LgogKiAgc2F2aW5nICAtIFRSVUUgaWYgdGhlIGZpbGUgd2lsbCBiZSBzYXZlZCB0bywgRkFMU0UgaWYgaXQgd2lsbCBiZSBvcGVuZWQuCiAqICB0aXRsZSAgIC0gVGl0bGUgbWVzc2FnZSBmb3IgdGhlIGZpbGUgYnJvd3NlciBkaWFsb2cuCiAqICBkZmx0ICAgIC0gRGVmYXVsdCBuYW1lIG9mIGZpbGUuCiAqICBleHQgICAgIC0gRGVmYXVsdCBleHRlbnNpb24gdG8gYmUgYWRkZWQgdG8gZmlsZXMgd2l0aG91dCBleHRlbnNpb25zLgogKiAgaW5pdGRpciAtIGRpcmVjdG9yeSBpbiB3aGljaCB0byBvcGVuIHRoZSBicm93c2VyIChOVUxMID0gY3VycmVudCBkaXIpCiAqICBmaWx0ZXIgIC0gRmlsdGVyIGZvciBtYXRjaGVkIGZpbGVzIHRvIGNob29zZSBmcm9tLgogKiAgSGFzIGEgZm9ybWF0IGxpa2UgdGhpczoKICogICJDIEZpbGVzICgqLmMpXDAqLmNcMCIKICogICJBbGwgRmlsZXNcMCouKlwwXDAiCiAqICBJZiB0aGVzZSB0d28gc3RyaW5ncyB3ZXJlIGNvbmNhdGVuYXRlZCwgdGhlbiBhIGNob2ljZSBvZiB0d28gZmlsZQogKiAgZmlsdGVycyB3aWxsIGJlIHNlbGVjdGFibGUgdG8gdGhlIHVzZXIuICBUaGVuIG9ubHkgbWF0Y2hpbmcgZmlsZXMgd2lsbAogKiAgYmUgc2hvd24gaW4gdGhlIGJyb3dzZXIuICBJZiBOVUxMLCB0aGUgZGVmYXVsdCBhbGxvd3MgYWxsIGZpbGVzLgogKgogKiAgKk5PVEUqIC0gdGhlIGZpbHRlciBzdHJpbmcgbXVzdCBiZSB0ZXJtaW5hdGVkIHdpdGggVFdPIG51bGxzLgogKi8KICAgIGNoYXJfdSAqCmd1aV9tY2hfYnJvd3NlKAogICAgaW50IHNhdmluZywKICAgIGNoYXJfdSAqdGl0bGUsCiAgICBjaGFyX3UgKmRmbHQsCiAgICBjaGFyX3UgKmV4dCwKICAgIGNoYXJfdSAqaW5pdGRpciwKICAgIGNoYXJfdSAqZmlsdGVyKQp7CiAgICAvKiBUT0RPOiBBZGQgQW1tb24ncyBzYWZldHkgY2hlY2wgKERhbnkpICovCiAgICBOYXZSZXBseVJlY29yZAlyZXBseTsKICAgIGNoYXJfdQkJKmZuYW1lID0gTlVMTDsKICAgIGNoYXJfdQkJKipmbmFtZXMgPSBOVUxMOwogICAgbG9uZwkJbnVtRmlsZXM7CiAgICBOYXZEaWFsb2dPcHRpb25zCW5hdk9wdGlvbnM7CiAgICBPU0VycgkJZXJyb3I7CgogICAgLyogR2V0IE5hdmlnYXRpb24gU2VydmljZSBEZWZhdWx0cyB2YWx1ZSAqLwogICAgTmF2R2V0RGVmYXVsdERpYWxvZ09wdGlvbnMoJm5hdk9wdGlvbnMpOwoKCiAgICAvKiBUT0RPOiBJZiB3ZSBnZXQgYSA6YnJvd3NlIGFyZ3MsIHNldCB0aGUgTXVsdGlwbGUgYml0LiAqLwogICAgbmF2T3B0aW9ucy5kaWFsb2dPcHRpb25GbGFncyA9ICBrTmF2QWxsb3dJbnZpc2libGVGaWxlcwoJCQkJIHwgIGtOYXZEb250QXV0b1RyYW5zbGF0ZQoJCQkJIHwgIGtOYXZEb250QWRkVHJhbnNsYXRlSXRlbXMKCQkJICAgIC8qCSB8ICBrTmF2QWxsb3dNdWx0aXBsZUZpbGVzICovCgkJCQkgfCAga05hdkFsbG93U3RhdGlvbmVyeTsKCiAgICAodm9pZCkgQzJQYXNjYWxTdHJpbmcodGl0bGUsICAgJm5hdk9wdGlvbnMubWVzc2FnZSk7CiAgICAodm9pZCkgQzJQYXNjYWxTdHJpbmcoZGZsdCwgICAgJm5hdk9wdGlvbnMuc2F2ZWRGaWxlTmFtZSk7CiAgICAvKiBDb3VsZCBzZXQgY2xpZW50TmFtZT8KICAgICAqCQkgd2luZG93VGl0bGU/ICh0aGVyZSdzIG5vIHRpdGxlIGJhcj8pCiAgICAgKi8KCiAgICBpZiAoc2F2aW5nKQogICAgewoJLyogQ2hhbmdlIGZpcnN0IHBhcm0gQUVEZXNjICh0eXBlRlNTKSAqZGVmYXVsdExvY2F0aW9uIHRvIG1hdGNoIGRmbHQgKi8KCU5hdlB1dEZpbGUoTlVMTCwgJnJlcGx5LCAmbmF2T3B0aW9ucywgTlVMTCwgJ1RFWFQnLCAnVklNIScsIE5VTEwpOwoJaWYgKCFyZXBseS52YWxpZFJlY29yZCkKCSAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIGVsc2UKICAgIHsKCS8qIENoYW5nZSBmaXJzdCBwYXJtIEFFRGVzYyAodHlwZUZTUykgKmRlZmF1bHRMb2NhdGlvbiB0byBtYXRjaCBkZmx0ICovCglOYXZHZXRGaWxlKE5VTEwsICZyZXBseSwgJm5hdk9wdGlvbnMsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJaWYgKCFyZXBseS52YWxpZFJlY29yZCkKCSAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBmbmFtZXMgPSBuZXdfZm5hbWVzX2Zyb21fQUVEZXNjKCZyZXBseS5zZWxlY3Rpb24sICZudW1GaWxlcywgJmVycm9yKTsKCiAgICBOYXZEaXNwb3NlUmVwbHkoJnJlcGx5KTsKCiAgICBpZiAoZm5hbWVzKQogICAgewoJZm5hbWUgPSBmbmFtZXNbMF07Cgl2aW1fZnJlZShmbmFtZXMpOwogICAgfQoKICAgIC8qIFRPRE86IFNob3J0ZW4gdGhlIGZpbGUgbmFtZSBpZiBwb3NzaWJsZSAqLwogICAgcmV0dXJuIGZuYW1lOwp9CiNlbmRpZiAvKiBGRUFUX0JST1dTRSAqLwoKI2lmZGVmIEZFQVRfR1VJX0RJQUxPRwovKgogKiBTdHVmZiBmb3IgZGlhbG9ndWVzCiAqLwoKLyoKICogQ3JlYXRlIGEgZGlhbG9ndWUgZHluYW1pY2FsbHkgZnJvbSB0aGUgcGFyYW1ldGVyIHN0cmluZ3MuCiAqIHR5cGUgICAgICAgPSB0eXBlIG9mIGRpYWxvZ3VlIChxdWVzdGlvbiwgYWxlcnQsIGV0Yy4pCiAqIHRpdGxlICAgICAgPSBkaWFsb2d1ZSB0aXRsZS4gbWF5IGJlIE5VTEwgZm9yIGRlZmF1bHQgdGl0bGUuCiAqIG1lc3NhZ2UgICAgPSB0ZXh0IHRvIGRpc3BsYXkuIERpYWxvZ3VlIHNpemVzIHRvIGFjY29tbW9kYXRlIGl0LgogKiBidXR0b25zICAgID0gJ1xuJyBzZXBhcmF0ZWQgbGlzdCBvZiBidXR0b24gY2FwdGlvbnMsIGRlZmF1bHQgZmlyc3QuCiAqIGRmbHRidXR0b24gPSBudW1iZXIgb2YgZGVmYXVsdCBidXR0b24uCiAqCiAqIFRoaXMgcm91dGluZSByZXR1cm5zIDEgaWYgdGhlIGZpcnN0IGJ1dHRvbiBpcyBwcmVzc2VkLAogKgkgICAgMiBmb3IgdGhlIHNlY29uZCwgZXRjLgogKgogKgkgICAgMCBpbmRpY2F0ZXMgRXNjIHdhcyBwcmVzc2VkLgogKgkgICAgLTEgZm9yIHVuZXhwZWN0ZWQgZXJyb3IKICoKICogSWYgc3R1YmJpbmcgb3V0IHRoaXMgZm4sIHJldHVybiAxLgogKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIHNob3J0ICAgaWR4OwogICAgc2hvcnQgICB3aWR0aDsJLyogU2l6ZSBvZiB0aGUgdGV4dCBpbiBwaXhlbCAqLwogICAgUmVjdCAgICBib3g7Cn0gdmdtRGxnSXRtOyAvKiBWaW0gR3VpX01hYy5jIERpYWxvZyBJdGVtICovCgojZGVmaW5lIE1vdmVSZWN0VG8ocix4LHkpIE9mZnNldFJlY3Qocix4LXItPmxlZnQseS1yLT50b3ApCgogICAgc3RhdGljIHZvaWQKbWFjTW92ZURpYWxvZ0l0ZW0oCiAgICBEaWFsb2dSZWYJdGhlRGlhbG9nLAogICAgc2hvcnQJaXRlbU51bWJlciwKICAgIHNob3J0CVgsCiAgICBzaG9ydAlZLAogICAgUmVjdAkqaW5Cb3gpCnsKI2lmIDAgLyogVVNFX0NBUkJPTklaRUQgKi8KICAgIC8qIFVudGVzdGVkICovCiAgICBNb3ZlRGlhbG9nSXRlbSh0aGVEaWFsb2csIGl0ZW1OdW1iZXIsIFgsIFkpOwogICAgaWYgKGluQm94ICE9IG5pbCkKCUdldERpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpdGVtTnVtYmVyLCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCBpbkJveCk7CiNlbHNlCiAgICBzaG9ydAlpdGVtVHlwZTsKICAgIEhhbmRsZQlpdGVtSGFuZGxlOwogICAgUmVjdAlsb2NhbEJveDsKICAgIFJlY3QJKml0ZW1Cb3ggPSAmbG9jYWxCb3g7CgogICAgaWYgKGluQm94ICE9IG5pbCkKCWl0ZW1Cb3ggPSBpbkJveDsKCiAgICBHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaXRlbU51bWJlciwgJml0ZW1UeXBlLCAmaXRlbUhhbmRsZSwgaXRlbUJveCk7CiAgICBPZmZzZXRSZWN0KGl0ZW1Cb3gsIC1pdGVtQm94LT5sZWZ0LCAtaXRlbUJveC0+dG9wKTsKICAgIE9mZnNldFJlY3QoaXRlbUJveCwgWCwgWSk7CiAgICAvKiBUbyBtb3ZlIGEgY29udHJvbCAobGlrZSBhIGJ1dHRvbikgd2UgbmVlZCB0byBjYWxsIGJvdGgKICAgICAqIE1vdmVDb250cm9sIGFuZCBTZXREaWFsb2dJdGVtLiBGQVEgNi0xOCAqLwogICAgaWYgKDEpIC8qKGl0ZW1UeXBlICYga0NvbnRyb2xEaWFsb2dJdGVtKSAqLwoJTW92ZUNvbnRyb2woKENvbnRyb2xSZWYpIGl0ZW1IYW5kbGUsIFgsIFkpOwogICAgU2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGl0ZW1OdW1iZXIsIGl0ZW1UeXBlLCBpdGVtSGFuZGxlLCBpdGVtQm94KTsKI2VuZGlmCn0KCiAgICBzdGF0aWMgdm9pZAptYWNTaXplRGlhbG9nSXRlbSgKICAgIERpYWxvZ1JlZgl0aGVEaWFsb2csCiAgICBzaG9ydAlpdGVtTnVtYmVyLAogICAgc2hvcnQJd2lkdGgsCiAgICBzaG9ydAloZWlnaHQpCnsKICAgIHNob3J0CWl0ZW1UeXBlOwogICAgSGFuZGxlCWl0ZW1IYW5kbGU7CiAgICBSZWN0CWl0ZW1Cb3g7CgogICAgR2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGl0ZW1OdW1iZXIsICZpdGVtVHlwZSwgJml0ZW1IYW5kbGUsICZpdGVtQm94KTsKCiAgICAvKiBXaGVuIHdpZHRoIG9yIGhlaWdodCBpcyB6ZXJvIGRvIG5vdCBjaGFuZ2UgaXQgKi8KICAgIGlmICh3aWR0aCAgPT0gMCkKCXdpZHRoICA9IGl0ZW1Cb3gucmlnaHQgIC0gaXRlbUJveC5sZWZ0OwogICAgaWYgKGhlaWdodCA9PSAwKQoJaGVpZ2h0ID0gaXRlbUJveC5ib3R0b20gLSBpdGVtQm94LnRvcDsKCiNpZiAwIC8qIFVTRV9DQVJCT05JWkVEICovCiAgICBTaXplRGlhbG9nSXRlbSh0aGVEaWFsb2csIGl0ZW1OdW1iZXIsIHdpZHRoLCBoZWlnaHQpOyAvKiBVbnRlc3RlZCAqLwojZWxzZQogICAgLyogUmVzaXplIHRoZSBib3VuZGluZyBib3ggKi8KICAgIGl0ZW1Cb3gucmlnaHQgID0gaXRlbUJveC5sZWZ0ICsgd2lkdGg7CiAgICBpdGVtQm94LmJvdHRvbSA9IGl0ZW1Cb3gudG9wICArIGhlaWdodDsKCiAgICAvKiBUbyByZXNpemUgYSBjb250cm9sIChsaWtlIGEgYnV0dG9uKSB3ZSBuZWVkIHRvIGNhbGwgYm90aAogICAgICogU2l6ZUNvbnRyb2wgYW5kIFNldERpYWxvZ0l0ZW0uIChkZWR1Y3RlZCBmcm9tIEZBUSA2LTE4KSAqLwogICAgaWYgKGl0ZW1UeXBlICYga0NvbnRyb2xEaWFsb2dJdGVtKQoJU2l6ZUNvbnRyb2woKENvbnRyb2xSZWYpIGl0ZW1IYW5kbGUsIHdpZHRoLCBoZWlnaHQpOwoKICAgIC8qIENvbmZpZ3VyZSBiYWNrIHRoZSBpdGVtICovCiAgICBTZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaXRlbU51bWJlciwgaXRlbVR5cGUsIGl0ZW1IYW5kbGUsICZpdGVtQm94KTsKI2VuZGlmCn0KCiAgICBzdGF0aWMgdm9pZAptYWNTZXREaWFsb2dJdGVtVGV4dCgKICAgIERpYWxvZ1JlZgl0aGVEaWFsb2csCiAgICBzaG9ydAlpdGVtTnVtYmVyLAogICAgU3RyMjU1CWl0ZW1OYW1lKQp7CiAgICBzaG9ydAlpdGVtVHlwZTsKICAgIEhhbmRsZQlpdGVtSGFuZGxlOwogICAgUmVjdAlpdGVtQm94OwoKICAgIEdldERpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpdGVtTnVtYmVyLCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCAmaXRlbUJveCk7CgogICAgaWYgKGl0ZW1UeXBlICYga0NvbnRyb2xEaWFsb2dJdGVtKQoJU2V0Q29udHJvbFRpdGxlKChDb250cm9sUmVmKSBpdGVtSGFuZGxlLCBpdGVtTmFtZSk7CiAgICBlbHNlCglTZXREaWFsb2dJdGVtVGV4dChpdGVtSGFuZGxlLCBpdGVtTmFtZSk7Cn0KCi8qIFRPRE86IFRoZXJlIGhhdmUgYmVlbiBzb21lIGNyYXNoZXMgd2l0aCBkaWFsb2dzLCBjaGVjayB5b3VyIGluYm94CiAqIChKdXNzaSkKICovCiAgICBpbnQKZ3VpX21jaF9kaWFsb2coCiAgICBpbnQJCXR5cGUsCiAgICBjaGFyX3UJKnRpdGxlLAogICAgY2hhcl91CSptZXNzYWdlLAogICAgY2hhcl91CSpidXR0b25zLAogICAgaW50CQlkZmx0YnV0dG9uLAogICAgY2hhcl91CSp0ZXh0ZmllbGQpCnsKICAgIEhhbmRsZQlidXR0b25ESVRMOwogICAgSGFuZGxlCWljb25ESVRMOwogICAgSGFuZGxlCWlucHV0RElUTDsKICAgIEhhbmRsZQltZXNzYWdlRElUTDsKICAgIEhhbmRsZQlpdGVtSGFuZGxlOwogICAgSGFuZGxlCWljb25IYW5kbGU7CiAgICBEaWFsb2dQdHIJdGhlRGlhbG9nOwogICAgY2hhcl91CWxlbjsKICAgIGNoYXJfdQlQYXNjYWxUaXRsZVsyNTZdOwkvKiBwbGFjZSBob2xkZXIgZm9yIHRoZSB0aXRsZSAqLwogICAgY2hhcl91CW5hbWVbMjU2XTsKICAgIEdyYWZQdHIJb2xkUG9ydDsKICAgIHNob3J0CWl0ZW1IaXQ7CiAgICBjaGFyX3UJKmJ1dHRvbkNoYXI7CiAgICBSZWN0CWJveDsKICAgIHNob3J0CWJ1dHRvbjsKICAgIHNob3J0CWxhc3RCdXR0b247CiAgICBzaG9ydAlpdGVtVHlwZTsKICAgIHNob3J0CXVzZUljb247CiAgICBzaG9ydAl3aWR0aDsKICAgIHNob3J0CXRvdGFsQnV0dG9uV2lkdGggPSAwOyAgIC8qIHRoZSB3aWR0aCBvZiBhbGwgYnV0dG9uIHRvZ2V0aGVyIGluY3VkaW5nIHNwYWNpbmcgKi8KICAgIHNob3J0CXdpZGVzdEJ1dHRvbiA9IDA7CiAgICBzaG9ydAlkZmx0QnV0dG9uRWRnZSAgICAgPSAyMDsgIC8qIGd1dCBmZWVsaW5nICovCiAgICBzaG9ydAlkZmx0RWxlbWVudFNwYWNpbmcgPSAxMzsgIC8qIGZyb20gSU06Vi4yLTI5ICovCiAgICBzaG9ydCAgICAgICBkZmx0SWNvblNpZGVTcGFjZSAgPSAyMzsgIC8qIGZyb20gSU06Vi4yLTI5ICovCiAgICBzaG9ydAltYXhpbXVtV2lkdGggICAgICAgPSA0MDA7IC8qIGd1dCBmZWVsaW5nICovCiAgICBzaG9ydAltYXhCdXR0b25XaWR0aAkgICA9IDE3NTsgLyogZ3V0IGZlZWxpbmcgKi8KCiAgICBzaG9ydAl2ZXJ0aWNhbDsKICAgIHNob3J0CWRpYWxvZ0hlaWdodDsKICAgIHNob3J0CW1lc3NhZ2VMaW5lcyA9IDM7CiAgICBGb250SW5mbwl0ZXh0Rm9udEluZm87CgogICAgdmdtRGxnSXRtICAgaWNvbkl0bTsKICAgIHZnbURsZ0l0bSAgIG1lc3NhZ2VJdG07CiAgICB2Z21EbGdJdG0gICBpbnB1dEl0bTsKICAgIHZnbURsZ0l0bSAgIGJ1dHRvbkl0bTsKCiAgICBXaW5kb3dSZWYJdGhlV2luZG93OwoKICAgIC8qIENoZWNrICd2JyBmbGFnIGluICdndWlvcHRpb25zJzogdmVydGljYWwgYnV0dG9uIHBsYWNlbWVudC4gKi8KICAgIHZlcnRpY2FsID0gKHZpbV9zdHJjaHIocF9nbywgR09fVkVSVElDQUwpICE9IE5VTEwpOwoKICAgIC8qIENyZWF0ZSBhIG5ldyBEaWFsb2cgQm94IGZyb20gdGVtcGxhdGUuICovCiAgICB0aGVEaWFsb2cgPSBHZXROZXdEaWFsb2coMTI5LCBuaWwsIChXaW5kb3dSZWYpIC0xKTsKCiAgICAvKiBHZXQgdGhlIFdpbmRvd1JlZiAqLwogICAgdGhlV2luZG93ID0gR2V0RGlhbG9nV2luZG93KHRoZURpYWxvZyk7CgogICAgLyogSGlkZSB0aGUgd2luZG93LgogICAgICogMS4gdG8gYXZvaWQgc2VlaW5nIHNsb3cgZHJhd2luZwogICAgICogMi4gdG8gcHJldmVudCBhIHByb2JsZW0gc2VlbiB3aGlsZSBtb3ZpbmcgZGlhbG9nIGl0ZW0KICAgICAqICAgIHdpdGhpbiBhIHZpc2libGUgd2luZG93LiAobm9uLUNhcmJvbiBNYWNPUyA5KQogICAgICogQ291bGQgYmUgYXZvaWRlZCBieSBjaGFuZ2luZyB0aGUgcmVzb3VyY2UuCiAgICAgKi8KICAgIEhpZGVXaW5kb3codGhlV2luZG93KTsKCiAgICAvKiBDaGFuZ2UgdGhlIGdyYXBoaWNhbCBwb3J0IHRvIHRoZSBkaWFsb2csCiAgICAgKiBzbyB3ZSBjYW4gbWVhc3VyZSB0aGUgdGV4dCB3aXRoIHRoZSBwcm9wZXIgZm9udCAqLwogICAgR2V0UG9ydCgmb2xkUG9ydCk7CiAgICBTZXRQb3J0RGlhbG9nUG9ydCh0aGVEaWFsb2cpOwoKICAgIC8qIEdldCB0aGUgaW5mbyBhYm91dCB0aGUgZGVmYXVsdCB0ZXh0LAogICAgICogdXNlZCB0byBjYWxjdWxhdGUgdGhlIGhlaWdodCBvZiB0aGUgbWVzc2FnZQogICAgICogYW5kIG9mIHRoZSAgdGV4dCBmaWVsZCAqLwogICAgR2V0Rm9udEluZm8oJnRleHRGb250SW5mbyk7CgogICAgLyoJU2V0IHRoZSBkaWFsb2cgdGl0bGUgKi8KICAgIGlmICh0aXRsZSAhPSBOVUxMKQogICAgewoJKHZvaWQpIEMyUGFzY2FsU3RyaW5nKHRpdGxlLCAmUGFzY2FsVGl0bGUpOwoJU2V0V1RpdGxlKHRoZVdpbmRvdywgUGFzY2FsVGl0bGUpOwogICAgfQoKICAgIC8qIENyZWF0ZXMgdGhlIGJ1dHRvbnMgYW5kIGFkZCB0aGVtIHRvIHRoZSBEaWFsb2cgQm94LiAqLwogICAgYnV0dG9uRElUTCA9IEdldFJlc291cmNlKCdESVRMJywgMTMwKTsKICAgIGJ1dHRvbkNoYXIgPSBidXR0b25zOwogICAgYnV0dG9uID0gMDsKCiAgICBmb3IgKDsqYnV0dG9uQ2hhciAhPSAwOykKICAgIHsKCS8qIEdldCB0aGUgbmFtZSBvZiB0aGUgYnV0dG9uICovCglidXR0b24rKzsKCWxlbiA9IDA7Cglmb3IgKDsoKCpidXR0b25DaGFyICE9IERMR19CVVRUT05fU0VQKSAmJiAoKmJ1dHRvbkNoYXIgIT0gMCkgJiYgKGxlbiA8IDI1NSkpOyBidXR0b25DaGFyKyspCgl7CgkgICAgaWYgKCpidXR0b25DaGFyICE9IERMR19IT1RLRVlfQ0hBUikKCQluYW1lWysrbGVuXSA9ICpidXR0b25DaGFyOwoJfQoJaWYgKCpidXR0b25DaGFyICE9IDApCgkgIGJ1dHRvbkNoYXIrKzsKCW5hbWVbMF0gPSBsZW47CgoJLyogQWRkIHRoZSBidXR0b24gKi8KCUFwcGVuZERJVEwodGhlRGlhbG9nLCBidXR0b25ESVRMLCBvdmVybGF5RElUTCk7IC8qIGFwcGVuZERJVExSaWdodCk7ICovCgoJLyogQ2hhbmdlIHRoZSBidXR0b24ncyBuYW1lICovCgltYWNTZXREaWFsb2dJdGVtVGV4dCh0aGVEaWFsb2csIGJ1dHRvbiwgbmFtZSk7CgoJLyogUmVzaXplIHRoZSBidXR0b24gdG8gZml0IGl0cyBuYW1lICovCgl3aWR0aCA9IFN0cmluZ1dpZHRoKG5hbWUpICsgMiAqIGRmbHRCdXR0b25FZGdlOwoJLyogTGltaXRlIHRoZSBzaXplIG9mIGFueSBidXR0b24gdG8gYW4gYWNjZXB0YWJsZSB2YWx1ZS4gKi8KCS8qIFRPRE86IFNob3VsZCBiZSBiYXNlZCBvbiB0aGUgbWVzc2FnZSB3aWR0aCAqLwoJaWYgKHdpZHRoID4gbWF4QnV0dG9uV2lkdGgpCgkgICAgd2lkdGggPSBtYXhCdXR0b25XaWR0aDsKCW1hY1NpemVEaWFsb2dJdGVtKHRoZURpYWxvZywgYnV0dG9uLCB3aWR0aCwgMCk7CgoJdG90YWxCdXR0b25XaWR0aCArPSB3aWR0aDsKCglpZiAod2lkdGggPiB3aWRlc3RCdXR0b24pCgkgICAgd2lkZXN0QnV0dG9uID0gd2lkdGg7CiAgICB9CiAgICBSZWxlYXNlUmVzb3VyY2UoYnV0dG9uRElUTCk7CiAgICBsYXN0QnV0dG9uID0gYnV0dG9uOwoKICAgIC8qIEFkZCB0aGUgaWNvbiB0byB0aGUgRGlhbG9nIEJveC4gKi8KICAgIGljb25JdG0uaWR4ID0gbGFzdEJ1dHRvbiArIDE7CiAgICBpY29uRElUTCA9IEdldFJlc291cmNlKCdESVRMJywgMTMxKTsKICAgIHN3aXRjaCAodHlwZSkKICAgIHsKCWNhc2UgVklNX0dFTkVSSUM6ICB1c2VJY29uID0ga05vdGVJY29uOwoJY2FzZSBWSU1fRVJST1I6ICAgIHVzZUljb24gPSBrU3RvcEljb247CgljYXNlIFZJTV9XQVJOSU5HOiAgdXNlSWNvbiA9IGtDYXV0aW9uSWNvbjsKCWNhc2UgVklNX0lORk86ICAgICB1c2VJY29uID0ga05vdGVJY29uOwoJY2FzZSBWSU1fUVVFU1RJT046IHVzZUljb24gPSBrTm90ZUljb247CglkZWZhdWx0OiAgICAgIHVzZUljb24gPSBrU3RvcEljb247CiAgICB9OwogICAgQXBwZW5kRElUTCh0aGVEaWFsb2csIGljb25ESVRMLCBvdmVybGF5RElUTCk7CiAgICBSZWxlYXNlUmVzb3VyY2UoaWNvbkRJVEwpOwogICAgR2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGljb25JdG0uaWR4LCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCAmYm94KTsKICAgIC8qIFRPRE86IFNob3VsZCB0aGUgaXRlbSBiZSBmcmVlZD8gKi8KICAgIGljb25IYW5kbGUgPSBHZXRJY29uKHVzZUljb24pOwogICAgU2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGljb25JdG0uaWR4LCBpdGVtVHlwZSwgaWNvbkhhbmRsZSwgJmJveCk7CgogICAgLyogQWRkIHRoZSBtZXNzYWdlIHRvIHRoZSBEaWFsb2cgYm94LiAqLwogICAgbWVzc2FnZUl0bS5pZHggPSBsYXN0QnV0dG9uICsgMjsKICAgIG1lc3NhZ2VESVRMID0gR2V0UmVzb3VyY2UoJ0RJVEwnLCAxMzIpOwogICAgQXBwZW5kRElUTCh0aGVEaWFsb2csIG1lc3NhZ2VESVRMLCBvdmVybGF5RElUTCk7CiAgICBSZWxlYXNlUmVzb3VyY2UobWVzc2FnZURJVEwpOwogICAgR2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIG1lc3NhZ2VJdG0uaWR4LCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCAmYm94KTsKICAgICh2b2lkKSBDMlBhc2NhbFN0cmluZyhtZXNzYWdlLCAmbmFtZSk7CiAgICBTZXREaWFsb2dJdGVtVGV4dChpdGVtSGFuZGxlLCBuYW1lKTsKICAgIG1lc3NhZ2VJdG0ud2lkdGggPSBTdHJpbmdXaWR0aChuYW1lKTsKCiAgICAvKiBBZGQgdGhlIGlucHV0IGJveCBpZiBuZWVkZWQgKi8KICAgIGlmICh0ZXh0ZmllbGQgIT0gTlVMTCkKICAgIHsKCS8qIENoZWF0IGZvciBub3cgcmV1c2UgdGhlIG1lc3NhZ2UgYW5kIGNvbnZlcnQgdG8gdGV4dCBlZGl0ICovCglpbnB1dEl0bS5pZHggPSBsYXN0QnV0dG9uICsgMzsKCWlucHV0RElUTCA9IEdldFJlc291cmNlKCdESVRMJywgMTMyKTsKCUFwcGVuZERJVEwodGhlRGlhbG9nLCBpbnB1dERJVEwsIG92ZXJsYXlESVRMKTsKCVJlbGVhc2VSZXNvdXJjZShpbnB1dERJVEwpOwoJR2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGlucHV0SXRtLmlkeCwgJml0ZW1UeXBlLCAmaXRlbUhhbmRsZSwgJmJveCk7Ci8qCSAgU2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGlucHV0SXRtLmlkeCwga0VkaXRUZXh0RGlhbG9nSXRlbSwgaXRlbUhhbmRsZSwgJmJveCk7Ki8KCSh2b2lkKSBDMlBhc2NhbFN0cmluZyh0ZXh0ZmllbGQsICZuYW1lKTsKCVNldERpYWxvZ0l0ZW1UZXh0KGl0ZW1IYW5kbGUsIG5hbWUpOwoJaW5wdXRJdG0ud2lkdGggPSBTdHJpbmdXaWR0aChuYW1lKTsKICAgIH0KCiAgICAvKiBTZXQgdGhlIDxFTlRFUj4gYW5kIDxFU0M+IGJ1dHRvbi4gKi8KICAgIFNldERpYWxvZ0RlZmF1bHRJdGVtKHRoZURpYWxvZywgZGZsdGJ1dHRvbik7CiAgICBTZXREaWFsb2dDYW5jZWxJdGVtKHRoZURpYWxvZywgMCk7CgogICAgLyogUmVwb3NpdGlvbiBlbGVtZW50ICovCgogICAgLyogQ2hlY2sgaWYgd2UgbmVlZCB0byBmb3JjZSB2ZXJ0aWNhbCAqLwogICAgaWYgKHRvdGFsQnV0dG9uV2lkdGggPiBtYXhpbXVtV2lkdGgpCgl2ZXJ0aWNhbCA9IFRSVUU7CgogICAgLyogUGxhY2UgaWNvbiAqLwogICAgbWFjTW92ZURpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpY29uSXRtLmlkeCwgZGZsdEljb25TaWRlU3BhY2UsIGRmbHRFbGVtZW50U3BhY2luZywgJmJveCk7CiAgICBpY29uSXRtLmJveC5yaWdodCA9IGJveC5yaWdodDsKICAgIGljb25JdG0uYm94LmJvdHRvbSA9IGJveC5ib3R0b207CgogICAgLyogUGxhY2UgTWVzc2FnZSAqLwogICAgbWVzc2FnZUl0bS5ib3gubGVmdCA9IGljb25JdG0uYm94LnJpZ2h0ICsgZGZsdEljb25TaWRlU3BhY2U7CiAgICBtYWNTaXplRGlhbG9nSXRlbSh0aGVEaWFsb2csIG1lc3NhZ2VJdG0uaWR4LCAwLCAgbWVzc2FnZUxpbmVzICogKHRleHRGb250SW5mby5hc2NlbnQgKyB0ZXh0Rm9udEluZm8uZGVzY2VudCkpOwogICAgbWFjTW92ZURpYWxvZ0l0ZW0odGhlRGlhbG9nLCBtZXNzYWdlSXRtLmlkeCwgbWVzc2FnZUl0bS5ib3gubGVmdCwgZGZsdEVsZW1lbnRTcGFjaW5nLCAmbWVzc2FnZUl0bS5ib3gpOwoKICAgIC8qIFBsYWNlIElucHV0ICovCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCiAgICB7CglpbnB1dEl0bS5ib3gubGVmdCA9IG1lc3NhZ2VJdG0uYm94LmxlZnQ7CglpbnB1dEl0bS5ib3gudG9wICA9IG1lc3NhZ2VJdG0uYm94LmJvdHRvbSArIGRmbHRFbGVtZW50U3BhY2luZzsKCW1hY1NpemVEaWFsb2dJdGVtKHRoZURpYWxvZywgaW5wdXRJdG0uaWR4LCAwLCB0ZXh0Rm9udEluZm8uYXNjZW50ICsgdGV4dEZvbnRJbmZvLmRlc2NlbnQpOwoJbWFjTW92ZURpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpbnB1dEl0bS5pZHgsIGlucHV0SXRtLmJveC5sZWZ0LCBpbnB1dEl0bS5ib3gudG9wLCAmaW5wdXRJdG0uYm94KTsKCS8qIENvbnZlcnQgdGhlIHN0YXRpYyB0ZXh0IGludG8gYSB0ZXh0IGVkaXQuCgkgKiBGb3Igc29tZSByZWFzb24gdGhpcyBjaGFuZ2UgbmVlZCB0byBiZSBkb25lIGxhc3QgKERhbnkpICovCglHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgaW5wdXRJdG0uaWR4LCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCAmaW5wdXRJdG0uYm94KTsKCVNldERpYWxvZ0l0ZW0odGhlRGlhbG9nLCBpbnB1dEl0bS5pZHgsIGtFZGl0VGV4dERpYWxvZ0l0ZW0sIGl0ZW1IYW5kbGUsICZpbnB1dEl0bS5ib3gpOwoJU2VsZWN0RGlhbG9nSXRlbVRleHQodGhlRGlhbG9nLCBpbnB1dEl0bS5pZHgsIDAsIDMyNzY3KTsKICAgIH0KCiAgICAvKiBQbGFjZSBCdXR0b24gKi8KICAgIGlmICh0ZXh0ZmllbGQgIT0gTlVMTCkKICAgIHsKCWJ1dHRvbkl0bS5ib3gubGVmdCA9IGlucHV0SXRtLmJveC5sZWZ0OwoJYnV0dG9uSXRtLmJveC50b3AgID0gaW5wdXRJdG0uYm94LmJvdHRvbSArIGRmbHRFbGVtZW50U3BhY2luZzsKICAgIH0KICAgIGVsc2UKICAgIHsKCWJ1dHRvbkl0bS5ib3gubGVmdCA9IG1lc3NhZ2VJdG0uYm94LmxlZnQ7CglidXR0b25JdG0uYm94LnRvcCAgPSBtZXNzYWdlSXRtLmJveC5ib3R0b20gKyBkZmx0RWxlbWVudFNwYWNpbmc7CiAgICB9CgogICAgZm9yIChidXR0b249MTsgYnV0dG9uIDw9IGxhc3RCdXR0b247IGJ1dHRvbisrKQogICAgewoKCW1hY01vdmVEaWFsb2dJdGVtKHRoZURpYWxvZywgYnV0dG9uLCBidXR0b25JdG0uYm94LmxlZnQsIGJ1dHRvbkl0bS5ib3gudG9wLCAmYm94KTsKCS8qIFdpdGggdmVydGljYWwsIGl0J3MgYmV0dGVyIHRvIGhhdmUgYWxsIGJ1dHRvbiB0aGUgc2FtZSBsZW5naHQgKi8KCWlmICh2ZXJ0aWNhbCkKCXsKCSAgICBtYWNTaXplRGlhbG9nSXRlbSh0aGVEaWFsb2csIGJ1dHRvbiwgd2lkZXN0QnV0dG9uLCAwKTsKCSAgICBHZXREaWFsb2dJdGVtKHRoZURpYWxvZywgYnV0dG9uLCAmaXRlbVR5cGUsICZpdGVtSGFuZGxlLCAmYm94KTsKCX0KCS8qIENhbGN1bGF0ZSBwb3NpdGlvbiBvZiBuZXh0IGJ1dHRvbiAqLwoJaWYgKHZlcnRpY2FsKQoJICAgIGJ1dHRvbkl0bS5ib3gudG9wICA9IGJveC5ib3R0b20gKyBkZmx0RWxlbWVudFNwYWNpbmc7CgllbHNlCgkgICAgYnV0dG9uSXRtLmJveC5sZWZ0ICA9IGJveC5yaWdodCArIGRmbHRFbGVtZW50U3BhY2luZzsKICAgIH0KCiAgICAvKiBSZXNpemUgdGhlIGRpYWxvZyBib3ggKi8KICAgIGRpYWxvZ0hlaWdodCA9IGJveC5ib3R0b20gKyBkZmx0RWxlbWVudFNwYWNpbmc7CiAgICBTaXplV2luZG93KHRoZVdpbmRvdywgbWF4aW11bVdpZHRoLCBkaWFsb2dIZWlnaHQsIFRSVUUpOwoKICAgIC8qIE1hZ2ljIHJlc2l6ZSAqLwogICAgQXV0b1NpemVEaWFsb2codGhlRGlhbG9nKTsKICAgIC8qIE5lZWQgYSBob3Jpem9udGFsIHJlc2l6ZSBhbnl3YXkgc28gbm90IHRoYXQgdXNlZnVsICovCgogICAgLyogRGlzcGxheSBpdCAqLwogICAgU2hvd1dpbmRvdyh0aGVXaW5kb3cpOwovKiAgQnJpbmdUb0Zyb250KHRoZVdpbmRvdyk7ICovCiAgICBTZWxlY3RXaW5kb3codGhlV2luZG93KTsKCi8qICBEcmF3RGlhbG9nKHRoZURpYWxvZyk7ICovCiNpZiAwCiAgICBHZXRQb3J0KCZvbGRQb3J0KTsKICAgIFNldFBvcnREaWFsb2dQb3J0KHRoZURpYWxvZyk7CiNlbmRpZgoKI2lmZGVmIFVTRV9DQVJCT05LRVlIQU5ETEVSCiAgICAvKiBBdm9pZCB0aGF0IHdlIHVzZSBrZXkgZXZlbnRzIGZvciB0aGUgbWFpbiB3aW5kb3cuICovCiAgICBkaWFsb2dfYnVzeSA9IFRSVUU7CiNlbmRpZgoKICAgIC8qIEhhbmcgdW50aWwgb25lIG9mIHRoZSBidXR0b24gaXMgaGl0ICovCiAgICBkbwogICAgewoJTW9kYWxEaWFsb2cobmlsLCAmaXRlbUhpdCk7CiAgICB9IHdoaWxlICgoaXRlbUhpdCA8IDEpIHx8IChpdGVtSGl0ID4gbGFzdEJ1dHRvbikpOwoKI2lmZGVmIFVTRV9DQVJCT05LRVlIQU5ETEVSCiAgICBkaWFsb2dfYnVzeSA9IEZBTFNFOwojZW5kaWYKCiAgICAvKiBDb3B5IGJhY2sgdGhlIHRleHQgZW50ZXJlZCBieSB0aGUgdXNlciBpbnRvIHRoZSBwYXJhbSAqLwogICAgaWYgKHRleHRmaWVsZCAhPSBOVUxMKQogICAgewoJR2V0RGlhbG9nSXRlbSh0aGVEaWFsb2csIGlucHV0SXRtLmlkeCwgJml0ZW1UeXBlLCAmaXRlbUhhbmRsZSwgJmJveCk7CglHZXREaWFsb2dJdGVtVGV4dChpdGVtSGFuZGxlLCAoY2hhcl91ICopICZuYW1lKTsKI2lmIElPU0laRSA8IDI1NgoJLyogVHJ1bmNhdGUgdGhlIG5hbWUgdG8gSU9TSVpFIGlmIG5lZWRlZCAqLwoJaWYgKG5hbWVbMF0gPiBJT1NJWkUpCgkgICAgbmFtZVswXSA9IElPU0laRSAtIDE7CiNlbmRpZgoJdmltX3N0cm5jcHkodGV4dGZpZWxkLCAmbmFtZVsxXSwgbmFtZVswXSk7CiAgICB9CgogICAgLyogUmVzdG9yZSB0aGUgb3JpZ2luYWwgZ3JhcGhpY2FsIHBvcnQgKi8KICAgIFNldFBvcnQob2xkUG9ydCk7CgogICAgLyogR2V0IHJpZGUgb2YgdGggZWRpYWxvZyAoZnJlZSBtZW1vcnkpICovCiAgICBEaXNwb3NlRGlhbG9nKHRoZURpYWxvZyk7CgogICAgcmV0dXJuIGl0ZW1IaXQ7Ci8qCiAqIFVzZWZ1bGwgdGhpbmcgd2hpY2ggY291bGQgYmUgdXNlZAogKiBTZXREaWFsb2dUaW1lb3V0KCk6IEF1dG8gY2xpY2sgYSBidXR0b24gYWZ0ZXIgdGltZW91dAogKiBTZXREaWFsb2dUcmFja3NDdXJzb3IoKSA6IEdldCB0aGUgSS1iZWFtIGN1cnNvciBvdmVyIGlucHV0IGJveAogKiBNb3ZlRGlhbG9nSXRlbSgpOgkgICAgUHJvYmFibHkgYmV0dGVyIHRoYW4gU2V0RGlhbG9nSXRlbQogKiBTaXplRGlhbG9nSXRlbSgpOgkJKGJ1dCBpcyBpdCBDYXJib24gT25seT8pCiAqIEF1dG9TaXplRGlhbG9nKCk6CSAgICBNYWdpYyByZXNpemUgb2YgZGlhbG9nIGJhc2VkIG9uIHRleHQgbGVuZ2h0CiAqLwp9CiNlbmRpZiAvKiBGRUFUX0RJQUxPR19HVUkgKi8KCi8qCiAqIERpc3BsYXkgdGhlIHNhdmVkIGVycm9yIG1lc3NhZ2UocykuCiAqLwojaWZkZWYgVVNFX01DSF9FUlJNU0cKICAgIHZvaWQKZGlzcGxheV9lcnJvcnModm9pZCkKewogICAgY2hhcgkqcDsKICAgIGNoYXJfdQlwRXJyb3JbMjU2XTsKCiAgICBpZiAoZXJyb3JfZ2EuZ2FfZGF0YSA9PSBOVUxMKQoJcmV0dXJuOwoKICAgIC8qIGF2b2lkIHB1dHRpbmcgdXAgYSBtZXNzYWdlIGJveCB3aXRoIGJsYW5rcyBvbmx5ICovCiAgICBmb3IgKHAgPSAoY2hhciAqKWVycm9yX2dhLmdhX2RhdGE7ICpwOyArK3ApCglpZiAoIWlzc3BhY2UoKnApKQoJewoJICAgIGlmIChTVFJMRU4ocCkgPiAyNTUpCgkJcEVycm9yWzBdID0gMjU1OwoJICAgIGVsc2UKCQlwRXJyb3JbMF0gPSBTVFJMRU4ocCk7CgoJICAgIFNUUk5DUFkoJnBFcnJvclsxXSwgcCwgcEVycm9yWzBdKTsKCSAgICBQYXJhbVRleHQocEVycm9yLCBuaWwsIG5pbCwgbmlsKTsKCSAgICBBbGVydCgxMjgsIG5pbCk7CgkgICAgYnJlYWs7CgkgICAgLyogVE9ETzogaGFuZGxlZCBtZXNzYWdlIGxvbmdlciB0aGFuIDI1NiBjaGFycwoJICAgICAqCSB1c2UgYXV0by1zaXplYWJsZSBhbGVydAoJICAgICAqCSBvciBkaWFsb2cgd2l0aCBzY3JvbGxiYXJzIChUZXh0RWRpdCB6b25lKQoJICAgICAqLwoJfQogICAgZ2FfY2xlYXIoJmVycm9yX2dhKTsKfQojZW5kaWYKCi8qCiAqIEdldCBjdXJyZW50IG1vdXNlIGNvb3JkaW5hdGVzIGluIHRleHQgd2luZG93LgogKi8KICAgIHZvaWQKZ3VpX21jaF9nZXRtb3VzZShpbnQgKngsIGludCAqeSkKewogICAgUG9pbnQgd2hlcmU7CgogICAgR2V0TW91c2UoJndoZXJlKTsKCiAgICAqeCA9IHdoZXJlLmg7CiAgICAqeSA9IHdoZXJlLnY7Cn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0bW91c2UoaW50IHgsIGludCB5KQp7CiAgICAvKiBUT0RPICovCiNpZiAwCiAgICAvKiBGcm9tIEZBUSAzLTExICovCgogICAgQ3Vyc29yRGV2aWNlUHRyIG15TW91c2U7CiAgICBQb2ludAkgICAgd2hlcmU7CgogICAgaWYgKCAgIE5HZXRUcmFwQWRkcmVzcyhfQ3Vyc29yRGV2aWNlRGlzcGF0Y2gsIFRvb2xUcmFwKQoJIT0gTkdldFRyYXBBZGRyZXNzKF9VbmltcGxlbWVudGVkLCAgIFRvb2xUcmFwKSkKICAgIHsKCS8qIE5ldyB3YXkgKi8KCgkvKgoJICogR2V0IGZpcnN0IGRldm9pY2Ugd2l0aCBvbmUgYnV0dG9uLgoJICogVGhpcyB3aWxsIHByb2JhYmx5IGJlIHRoZSBzdGFuZGFkIG1vdXNlCgkgKiBzdGFydGF0IGhlYWQgb2YgY3Vyc29yIGRldiBsaXN0CgkgKgoJICovCgoJbXlNb3VzZSA9IG5pbDsKCglkbwoJewoJICAgIC8qIEdldCB0aGUgbmV4dCBjdXJzb3IgZGV2aWNlICovCgkgICAgQ3Vyc29yRGV2aWNlTmV4dERldmljZSgmbXlNb3VzZSk7Cgl9Cgl3aGlsZSAoKG15TW91c2UgIT0gbmlsKSAmJiAobXlNb3VzZS0+Y250QnV0dG9ucyAhPSAxKSk7CgoJQ3Vyc29yRGV2aWNlTW92ZVRvKG15TW91c2UsIHgsIHkpOwogICAgfQogICAgZWxzZQogICAgewoJLyogT2xkIHdheSAqLwoJd2hlcmUuaCA9IHg7Cgl3aGVyZS52ID0geTsKCgkqKFBvaW50ICopUmF3TW91c2UgPSB3aGVyZTsKCSooUG9pbnQgKilNVGVtcCAgICA9IHdoZXJlOwoJKihQdHIpICAgIENyc3JOZXcgID0gMHhGRkZGOwogICAgfQojZW5kaWYKfQoKICAgIHZvaWQKZ3VpX21jaF9zaG93X3BvcHVwbWVudSh2aW1tZW51X1QgKm1lbnUpCnsKLyoKICogIENsb25lIFBvcFVwIHRvIHVzZSBtZW51CiAqICBDcmVhdGUgYSBvYmplY3QgZGVzY3JpcHRvciBmb3IgdGhlIGN1cnJlbnQgc2VsZWN0aW9uCiAqICBDYWxsIHRoZSBwcm9jZWR1cmUKICovCgogICAgTWVudUhhbmRsZQlDbnR4TWVudTsKICAgIFBvaW50CXdoZXJlOwogICAgT1NTdGF0dXMJc3RhdHVzOwogICAgVUludDMyCUNudHhUeXBlOwogICAgU0ludDE2CUNudHhNZW51SUQ7CiAgICBVSW50MTYJQ250eE1lbnVJdGVtOwogICAgU3RyMjU1CUhlbHBOYW1lID0gIiI7CiAgICBHcmFmUHRyCXNhdmVQb3J0OwoKICAgIC8qIFNhdmUgQ3VycmVudCBQb3J0OiBPbiBNYWNPUyBYIHdlIHNlZW0gdG8gbG9zZSB0aGUgcG9ydCAqLwogICAgR2V0UG9ydCgmc2F2ZVBvcnQpOyAvKk9TWCovCgogICAgR2V0TW91c2UoJndoZXJlKTsKICAgIExvY2FsVG9HbG9iYWwoJndoZXJlKTsgLypPU1gqLwogICAgQ250eE1lbnUgPSBtZW51LT5zdWJtZW51X2hhbmRsZTsKCiAgICAvKiBUT0RPOiBHZXQgdGhlIHRleHQgc2VsZWN0aW9uIGZyb20gVmltICovCgogICAgLyogQ2FsbCB0byBIYW5kbGUgUG9wdXAgKi8KICAgIHN0YXR1cyA9IENvbnRleHR1YWxNZW51U2VsZWN0KENudHhNZW51LCB3aGVyZSwgZmFsc2UsIGtDTUhlbHBJdGVtTm9IZWxwLCBIZWxwTmFtZSwgTlVMTCwgJkNudHhUeXBlLCAmQ250eE1lbnVJRCwgJkNudHhNZW51SXRlbSk7CgogICAgaWYgKHN0YXR1cyA9PSBub0VycikKICAgIHsKCWlmIChDbnR4VHlwZSA9PSBrQ01NZW51SXRlbVNlbGVjdGVkKQoJewoJICAgIC8qIEhhbmRsZSB0aGUgbWVudSBDbnR4TWVudUlELCBDbnR4TWVudUl0ZW0gKi8KCSAgICAvKiBUaGUgc3VibWVudSBjYW4gYmUgaGFuZGxlIGRpcmVjdGx5IGJ5IGd1aV9tYWNfaGFuZGxlX21lbnUgKi8KCSAgICAvKiBCdXQgd2hhdCBhYm91dCB0aGUgY3VycmVudCBtZW51LCBpcyB0aGUgbWVudSBjaGFuZ2VkIGJ5IENvbnRleHR1YWxNZW51U2VsZWN0ICovCgkgICAgZ3VpX21hY19oYW5kbGVfbWVudSgoQ250eE1lbnVJRCA8PCAxNikgKyBDbnR4TWVudUl0ZW0pOwoJfQoJZWxzZSBpZiAoQ250eE1lbnVJRCA9PSBrQ01TaG93SGVscFNlbGVjdGVkKQoJewoJICAgIC8qIFNob3VsZCBjb21lIHVwIHdpdGggdGhlIGhlbHAgKi8KCX0KICAgIH0KCiAgICAvKiBSZXN0b3JlIG9yaWdpbmFsIFBvcnQgKi8KICAgIFNldFBvcnQoc2F2ZVBvcnQpOyAvKk9TWCovCn0KCiNpZiBkZWZpbmVkKEZFQVRfQ1dfRURJVE9SKSB8fCBkZWZpbmVkKFBST1RPKQovKiBUT0RPOiBJcyBpdCBuZWVkIGZvciBNQUNPU19YPyAoRGFueSkgKi8KICAgIHZvaWQKbWNoX3Bvc3RfYnVmZmVyX3dyaXRlKGJ1Zl9UICpidWYpCnsKICAgIEdldEZTU3BlY0Zyb21QYXRoKGJ1Zi0+Yl9mZm5hbWUsICZidWYtPmJfRlNTcGVjKTsKICAgIFNlbmRfS0FITF9NT0RfQUUoYnVmKTsKfQojZW5kaWYKCiNpZmRlZiBGRUFUX1RJVExFCi8qCiAqIFNldCB0aGUgd2luZG93IHRpdGxlIGFuZCBpY29uLgogKiAoVGhlIGljb24gaXMgbm90IHRha2VuIGNhcmUgb2YpLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zZXR0aXRsZShjaGFyX3UgKnRpdGxlLCBjaGFyX3UgKmljb24pCnsKICAgIC8qIFRPRE86IEdldCB2aW0gdG8gbWFrZSBzdXJlIG1heGxlbiAoZnJvbSBwX3RpdGxlbGVuKSBpcyBzbWFsbGVyCiAgICAgKiAgICAgICB0aGF0IDI1Ni4gRXZlbiBiZXR0ZXIgZ2V0IGl0IHRvIGZpdCBuaWNlbHkgaW4gdGhlIHRpdGxlYmFyLgogICAgICovCiNpZmRlZiBNQUNPU19DT05WRVJUCiAgICBDRlN0cmluZ1JlZiB3aW5kb3dUaXRsZTsKICAgIHNpemVfdAl3aW5kb3dUaXRsZUxlbjsKI2Vsc2UKICAgIGNoYXJfdSAgICpwYXNjYWxUaXRsZTsKI2VuZGlmCgogICAgaWYgKHRpdGxlID09IE5VTEwpCQkvKiBub3RoaW5nIHRvIGRvICovCglyZXR1cm47CgojaWZkZWYgTUFDT1NfQ09OVkVSVAogICAgd2luZG93VGl0bGVMZW4gPSBTVFJMRU4odGl0bGUpOwogICAgd2luZG93VGl0bGUgID0gbWFjX2VuY190b19jZnN0cmluZyh0aXRsZSwgd2luZG93VGl0bGVMZW4pOwoKICAgIGlmICh3aW5kb3dUaXRsZSkKICAgIHsKCVNldFdpbmRvd1RpdGxlV2l0aENGU3RyaW5nKGd1aS5WaW1XaW5kb3csIHdpbmRvd1RpdGxlKTsKCUNGUmVsZWFzZSh3aW5kb3dUaXRsZSk7CiAgICB9CiNlbHNlCiAgICBwYXNjYWxUaXRsZSA9IEMyUGFzY2FsX3NhdmUodGl0bGUpOwogICAgaWYgKHBhc2NhbFRpdGxlICE9IE5VTEwpCiAgICB7CglTZXRXVGl0bGUoZ3VpLlZpbVdpbmRvdywgcGFzY2FsVGl0bGUpOwoJdmltX2ZyZWUocGFzY2FsVGl0bGUpOwogICAgfQojZW5kaWYKfQojZW5kaWYKCi8qCiAqIFRyYW5zZmVyZWQgZnJvbSBvc19tYWMuYyBmb3IgTWFjT1MgWCB1c2luZyBvc191bml4LmMgcHJlcCB3b3JrCiAqLwoKICAgIGludApDMlBhc2NhbFN0cmluZyhjaGFyX3UgKkNTdHJpbmcsIFN0cjI1NSAqUGFzY2FsU3RyaW5nKQp7CiAgICBjaGFyX3UgKlBhc2NhbFB0ciA9IChjaGFyX3UgKikgUGFzY2FsU3RyaW5nOwogICAgaW50ICAgIGxlbjsKICAgIGludCAgICBpOwoKICAgIFBhc2NhbFB0clswXSA9IDA7CiAgICBpZiAoQ1N0cmluZyA9PSBOVUxMKQoJcmV0dXJuIDA7CgogICAgbGVuID0gU1RSTEVOKENTdHJpbmcpOwogICAgaWYgKGxlbiA+IDI1NSkKCWxlbiA9IDI1NTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCglQYXNjYWxQdHJbaSsxXSA9IENTdHJpbmdbaV07CgogICAgUGFzY2FsUHRyWzBdID0gbGVuOwoKICAgIHJldHVybiAwOwp9CgogICAgaW50CkdldEZTU3BlY0Zyb21QYXRoKGNoYXJfdSAqZmlsZSwgRlNTcGVjICpmaWxlRlNTcGVjKQp7CiAgICAvKiBGcm9tIEZBUSA4LTEyICovCiAgICBTdHIyNTUgICAgICBmaWxlUGFzY2FsOwogICAgQ0luZm9QQlJlYwlteUNQQjsKICAgIE9TRXJyCWVycjsKCiAgICAodm9pZCkgQzJQYXNjYWxTdHJpbmcoZmlsZSwgJmZpbGVQYXNjYWwpOwoKICAgIG15Q1BCLmRpckluZm8uaW9OYW1lUHRyICAgPSBmaWxlUGFzY2FsOwogICAgbXlDUEIuZGlySW5mby5pb1ZSZWZOdW0gICA9IDA7CiAgICBteUNQQi5kaXJJbmZvLmlvRkRpckluZGV4ID0gMDsKICAgIG15Q1BCLmRpckluZm8uaW9EckRpcklEICAgPSAwOwoKICAgIGVycj0gUEJHZXRDYXRJbmZvKCZteUNQQiwgZmFsc2UpOwoKICAgIC8qICAgIHZSZWZOdW0sIGRpcklELCBuYW1lICovCiAgICBGU01ha2VGU1NwZWMoMCwgMCwgZmlsZVBhc2NhbCwgZmlsZUZTU3BlYyk7CgogICAgLyogVE9ETzogVXNlIGFuIGVycm9yIGNvZGUgbWVjaGFuaXNtICovCiAgICByZXR1cm4gMDsKfQoKLyoKICogQ29udmVydCBhIEZTU3BlYyB0byBhIGZ1aWxsIHBhdGgKICovCgpjaGFyX3UgKkZ1bGxQYXRoRnJvbUZTU3BlY19zYXZlKEZTU3BlYyBmaWxlKQp7CiAgICAvKgogICAgICogVE9ETzogQWRkIHByb3RlY3Rpb24gZm9yIDI1NiBjaGFyIG1heC4KICAgICAqLwoKICAgIENJbmZvUEJSZWMJdGhlQ1BCOwogICAgY2hhcl91CWZuYW1lWzI1Nl07CiAgICBjaGFyX3UJKmZpbGVuYW1lUHRyID0gZm5hbWU7CiAgICBPU0VycgllcnJvcjsKICAgIGludAkJZm9sZGVyID0gMTsKI2lmZGVmIFVTRV9VTklYRklMRU5BTUUKICAgIFNJbnQxNglkZmx0Vm9sX3ZSZWZOdW07CiAgICBTSW50MzIJZGZsdFZvbF9kaXJJRDsKICAgIEZTUmVmCXJlZkZpbGU7CiAgICBPU1N0YXR1cwlzdGF0dXM7CiAgICBVSW50MzIJcGF0aFNpemUgPSAyNTY7CiAgICBjaGFyX3UJcGF0aG5hbWVbMjU2XTsKICAgIGNoYXJfdQkqcGF0aCA9IHBhdGhuYW1lOwojZWxzZQogICAgU3RyMjU1CWRpcmVjdG9yeU5hbWU7CiAgICBjaGFyX3UJdGVtcG9yYXJ5WzI1NV07CiAgICBjaGFyX3UJKnRlbXBvcmFyeVB0ciA9IHRlbXBvcmFyeTsKI2VuZGlmCgojaWZkZWYgVVNFX1VOSVhGSUxFTkFNRQogICAgLyogR2V0IHRoZSBkZWZhdWx0IHZvbHVtZSAqLwogICAgLyogVE9ETzogUmVtb3ZlIGFzIHRoaXMgb25seSB3b3JrIGlmIFZpbSBpcyBvbiB0aGUgQm9vdCBWb2x1bWUqLwogICAgZXJyb3I9SEdldFZvbChOVUxMLCAmZGZsdFZvbF92UmVmTnVtLCAmZGZsdFZvbF9kaXJJRCk7CgogICAgaWYgKGVycm9yKQogICAgICByZXR1cm4gTlVMTDsKI2VuZGlmCgogICAgLyogU3RhcnQgZmlsbGluZyBmbmFtZSB3aXRoIGZpbGUubmFtZSAgKi8KICAgIHZpbV9zdHJuY3B5KGZpbGVuYW1lUHRyLCAmZmlsZS5uYW1lWzFdLCBmaWxlLm5hbWVbMF0pOwoKICAgIC8qIEdldCB0aGUgaW5mbyBhYm91dCB0aGUgZmlsZSBzcGVjaWZpZWQgaW4gRlNTcGVjICovCiAgICB0aGVDUEIuZGlySW5mby5pb0ZEaXJJbmRleCA9IDA7CiAgICB0aGVDUEIuZGlySW5mby5pb05hbWVQdHIgICA9IGZpbGUubmFtZTsKICAgIHRoZUNQQi5kaXJJbmZvLmlvVlJlZk51bSAgID0gZmlsZS52UmVmTnVtOwogIC8qdGhlQ1BCLmhGaWxlSW5mby5pb0RpcklEICAgPSAwOyovCiAgICB0aGVDUEIuZGlySW5mby5pb0RyRGlySUQgICA9IGZpbGUucGFySUQ7CgogICAgLyogQXMgaW9GRGlySW5kZXggPSAwLCBnZXQgdGhlIGluZm8gb2YgaW9OYW1lUHRyLAogICAgICAgd2hpY2ggaXMgcmVsYXRpdmUgdG8gaW9WcmVmTnVtLCBpb0RpcklEICovCiAgICBlcnJvciA9IFBCR2V0Q2F0SW5mbygmdGhlQ1BCLCBmYWxzZSk7CgogICAgLyogSWYgd2UgYXJlIGNhbGxlZCBmb3IgYSBuZXcgZmlsZSB3ZSBleHBlY3QgZm5mRXJyICovCiAgICBpZiAoKGVycm9yKSAmJiAoZXJyb3IgIT0gZm5mRXJyKSkKICAgICAgcmV0dXJuIE5VTEw7CgogICAgLyogQ2hlY2sgaWYgaXQncyBhIGZpbGUgb3IgZm9sZGVyICAgICAgICovCiAgICAvKiBkZWZhdWx0IHRvIGZpbGUgaWYgZmlsZSBkb24ndCBleGlzdCAgKi8KICAgIGlmICgoKHRoZUNQQi5oRmlsZUluZm8uaW9GbEF0dHJpYiAmIGlvRGlyTWFzaykgPT0gMCkgfHwgKGVycm9yKSkKICAgICAgZm9sZGVyID0gMDsgLyogSXQncyBub3QgYSBmb2xkZXIgKi8KICAgIGVsc2UKICAgICAgZm9sZGVyID0gMTsKCiNpZmRlZiBVU0VfVU5JWEZJTEVOQU1FCiAgICAvKgogICAgICogVGhlIGZ1bmN0aW9uIHVzZWQgaGVyZSBhcmUgYXZhaWxhYmxlIGluIENhcmJvbiwgYnV0CiAgICAgKiBkbyBub3RoaW5nIHVuZSBNYWNPUyA4IGFuZCA5CiAgICAgKi8KICAgIGlmIChlcnJvciA9PSBmbmZFcnIpCiAgICB7CgkvKiBJZiB0aGUgZmlsZSB0byBiZSBzYXZlZCBkb2VzIG5vdCBhbHJlYWR5IGV4aXN0LCBpdCBpc24ndCBwb3NzaWJsZQoJICAgdG8gY29udmVydCBpdHMgRlNTcGVjIGludG8gYW4gRlNSZWYuICBCdXQgd2UgY2FuIGNvbnN0cnVjdCBhbgoJICAgRlNTcGVjIGZvciB0aGUgZmlsZSdzIHBhcmVudCBmb2xkZXIgKHNpbmNlIHdlIGhhdmUgaXRzIHZvbHVtZSBhbmQKCSAgIGRpcmVjdG9yeSBJRHMpLCBhbmQgc2luY2UgdGhhdCBmb2xkZXIgZG9lcyBleGlzdCwgd2UgY2FuIGNvbnZlcnQKCSAgIHRoYXQgRlNTcGVjIGludG8gYW4gRlNSZWYsIGNvbnZlcnQgdGhlIEZTUmVmIGluIHR1cm4gaW50byBhIHBhdGgsCgkgICBhbmQsIGZpbmFsbHksIGFwcGVuZCB0aGUgZmlsZW5hbWUuICovCglGU1NwZWMgZGlyU3BlYzsKCUZTUmVmIGRpclJlZjsKCVN0cjI1NSBlbXB0eUZpbGVuYW1lID0gIlxwIjsKCWVycm9yID0gRlNNYWtlRlNTcGVjKHRoZUNQQi5kaXJJbmZvLmlvVlJlZk51bSwKCSAgICB0aGVDUEIuZGlySW5mby5pb0RyRGlySUQsIGVtcHR5RmlsZW5hbWUsICZkaXJTcGVjKTsKCWlmIChlcnJvcikKCSAgICByZXR1cm4gTlVMTDsKCgllcnJvciA9IEZTcE1ha2VGU1JlZigmZGlyU3BlYywgJmRpclJlZik7CglpZiAoZXJyb3IpCgkgICAgcmV0dXJuIE5VTEw7CgoJc3RhdHVzID0gRlNSZWZNYWtlUGF0aCgmZGlyUmVmLCAoVUludDgqKXBhdGgsIHBhdGhTaXplKTsKCWlmIChzdGF0dXMpCgkgICAgcmV0dXJuIE5VTEw7CgoJU1RSQ0FUKHBhdGgsICIvIik7CglTVFJDQVQocGF0aCwgZmlsZW5hbWVQdHIpOwogICAgfQogICAgZWxzZQogICAgewoJLyogSWYgdGhlIGZpbGUgdG8gYmUgc2F2ZWQgYWxyZWFkeSBleGlzdHMsIHdlIGNhbiBnZXQgaXRzIGZ1bGwgcGF0aAoJICAgYnkgY29udmVydGluZyBpdHMgRlNTcGVjIGludG8gYW4gRlNSZWYuICovCgllcnJvcj1GU3BNYWtlRlNSZWYoJmZpbGUsICZyZWZGaWxlKTsKCWlmIChlcnJvcikKCSAgICByZXR1cm4gTlVMTDsKCglzdGF0dXM9RlNSZWZNYWtlUGF0aCgmcmVmRmlsZSwgKFVJbnQ4ICopIHBhdGgsIHBhdGhTaXplKTsKCWlmIChzdGF0dXMpCgkgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyogQWRkIGEgc2xhc2ggYXQgdGhlIGVuZCBpZiBuZWVkZWQgKi8KICAgIGlmIChmb2xkZXIpCglTVFJDQVQocGF0aCwgIi8iKTsKCiAgICByZXR1cm4gKHZpbV9zdHJzYXZlKHBhdGgpKTsKI2Vsc2UKICAgIC8qIFRPRE86IEdldCByaWQgb2YgYWxsIFVTRV9VTklYRklMRU5BTUUgYmVsb3cgKi8KICAgIC8qIFNldCBpb05hbWVQdHIsIGl0J3MgdGhlIHNhbWUgYXJlYSB3aGljaCBpcyBhbHdheXMgcmV1c2VkLiAqLwogICAgdGhlQ1BCLmRpckluZm8uaW9OYW1lUHRyID0gZGlyZWN0b3J5TmFtZTsKCiAgICAvKiBUcmljayBmb3IgZmlyc3QgZW50cnksIHNldCBpb0RyUGFySUQgdG8gdGhlIGZpcnN0IHZhbHVlCiAgICAgKiB3ZSB3YW50IGZvciBpb0RyRGlySUQqLwogICAgdGhlQ1BCLmRpckluZm8uaW9EclBhcklEID0gZmlsZS5wYXJJRDsKICAgIHRoZUNQQi5kaXJJbmZvLmlvRHJEaXJJRCA9IGZpbGUucGFySUQ7CgogICAgaWYgKChUUlVFKSAmJiAoZmlsZS5wYXJJRCAhPSBmc1J0RGlySUQgLypmc1J0UGFySUQqLykpCiAgICBkbwogICAgewoJdGhlQ1BCLmRpckluZm8uaW9GRGlySW5kZXggPSAtMTsKICAgICAvKiB0aGVDUEIuZGlySW5mby5pb05hbWVQdHIgICA9IGRpcmVjdG9yeU5hbWU7IEFscmVhZHkgZG9uZSBhYm92ZS4gKi8KCXRoZUNQQi5kaXJJbmZvLmlvVlJlZk51bSAgID0gZmlsZS52UmVmTnVtOwogICAgIC8qIHRoZUNQQi5kaXJJbmZvLmlvRGlySUQgICAgID0gaXJyZXZlbGFudCB3aGVuIGlvRkRpckluZGV4ID0gLTEgKi8KCXRoZUNQQi5kaXJJbmZvLmlvRHJEaXJJRCAgID0gdGhlQ1BCLmRpckluZm8uaW9EclBhcklEOwoKCS8qIEFzIGlvRkRpckluZGV4ID0gLTEsIGdldCB0aGUgaW5mbyBvZiBpb0RyRGlySUQsICovCgkvKiAgKmlvTmFtZVB0clswIFRPIDMxXSB3aWxsIGJlIHVwZGF0ZWQJCSAgICovCgllcnJvciA9IFBCR2V0Q2F0SW5mbygmdGhlQ1BCLGZhbHNlKTsKCglpZiAoZXJyb3IpCgkgIHJldHVybiBOVUxMOwoKCS8qIFB1dCB0aGUgbmV3IGRpcmVjdG9yeU5hbWUgaW4gZnJvbnQgb2YgdGhlIGN1cnJlbnQgZm5hbWUgKi8KCVNUUkNQWSh0ZW1wb3JhcnlQdHIsIGZpbGVuYW1lUHRyKTsKCXZpbV9zdHJuY3B5KGZpbGVuYW1lUHRyLCAmZGlyZWN0b3J5TmFtZVsxXSwgZGlyZWN0b3J5TmFtZVswXSk7CglTVFJDQVQoZmlsZW5hbWVQdHIsICI6Iik7CglTVFJDQVQoZmlsZW5hbWVQdHIsIHRlbXBvcmFyeVB0cik7CiAgICB9CiNpZiAxIC8qIGRlZiBVU0VfVU5JWEZJTEVOQU1FICovCiAgICB3aGlsZSAoKHRoZUNQQi5kaXJJbmZvLmlvRHJQYXJJRCAhPSBmc1J0RGlySUQpIC8qICYmICovCgkgLyogICh0aGVDUEIuZGlySW5mby5pb0RyRGlySUQgIT0gZnNSdERpcklEKSovKTsKI2Vsc2UKICAgIHdoaWxlICh0aGVDUEIuZGlySW5mby5pb0RyRGlySUQgIT0gZnNSdERpcklEKTsKI2VuZGlmCgogICAgLyogR2V0IHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdm9sdW1lIG9uIHdoaWNoIHRoZSBmaWxlIHJlc2lkZSAqLwogICAgdGhlQ1BCLmRpckluZm8uaW9GRGlySW5kZXggPSAtMTsKIC8qIHRoZUNQQi5kaXJJbmZvLmlvTmFtZVB0ciAgID0gZGlyZWN0b3J5TmFtZTsgQWxyZWFkeSBkb25lIGFib3ZlLiAqLwogICAgdGhlQ1BCLmRpckluZm8uaW9WUmVmTnVtICAgPSBmaWxlLnZSZWZOdW07CiAvKiB0aGVDUEIuZGlySW5mby5pb0RpcklEICAgICA9IGlycmV2ZWxhbnQgd2hlbiBpb0ZEaXJJbmRleCA9IC0xICovCiAgICB0aGVDUEIuZGlySW5mby5pb0RyRGlySUQgICA9IHRoZUNQQi5kaXJJbmZvLmlvRHJQYXJJRDsKCiAgICAvKiBBcyBpb0ZEaXJJbmRleCA9IC0xLCBnZXQgdGhlIGluZm8gb2YgaW9EckRpcklELCAqLwogICAgLyoJKmlvTmFtZVB0clswIFRPIDMxXSB3aWxsIGJlIHVwZGF0ZWQJICAgICAgICovCiAgICBlcnJvciA9IFBCR2V0Q2F0SW5mbygmdGhlQ1BCLGZhbHNlKTsKCiAgICBpZiAoZXJyb3IpCiAgICAgIHJldHVybiBOVUxMOwoKICAgIC8qIEZvciBNYWNPUyBDbGFzc2ljIGFsd2F5cyBhZGQgdGhlIHZvbHVtZSBuYW1lCSAgICAgKi8KICAgIC8qIEZvciBNYWNPUyBYIGFkZCB0aGUgdm9sdW1lIG5hbWUgcHJlY2VkZWQgYnkgIlZvbHVtZXMiICovCiAgICAvKgl3aGVuIHdlIGFyZSBub3QgcmVmZXJpbmcgdG8gdGhlIGJvb3Qgdm9sdW1lCSAgICAgKi8KI2lmZGVmIFVTRV9VTklYRklMRU5BTUUKICAgIGlmIChmaWxlLnZSZWZOdW0gIT0gZGZsdFZvbF92UmVmTnVtKQojZW5kaWYKICAgIHsKCS8qIEFkZCB0aGUgdm9sdW1lIG5hbWUgKi8KCVNUUkNQWSh0ZW1wb3JhcnlQdHIsIGZpbGVuYW1lUHRyKTsKCXZpbV9zdHJuY3B5KGZpbGVuYW1lUHRyLCAmZGlyZWN0b3J5TmFtZVsxXSwgZGlyZWN0b3J5TmFtZVswXSk7CglTVFJDQVQoZmlsZW5hbWVQdHIsICI6Iik7CglTVFJDQVQoZmlsZW5hbWVQdHIsIHRlbXBvcmFyeVB0cik7CgojaWZkZWYgVVNFX1VOSVhGSUxFTkFNRQoJU1RSQ1BZKHRlbXBvcmFyeVB0ciwgZmlsZW5hbWVQdHIpOwoJZmlsZW5hbWVQdHJbMF0gPSAwOyAvKiBOVUxMIHRlcm1pbmF0ZSB0aGUgc3RyaW5nICovCglTVFJDQVQoZmlsZW5hbWVQdHIsICJWb2x1bWVzOiIpOwoJU1RSQ0FUKGZpbGVuYW1lUHRyLCB0ZW1wb3JhcnlQdHIpOwojZW5kaWYKICAgIH0KCiAgICAvKiBBcHBlbmQgZmluYWwgcGF0aCBzZXBhcmF0b3IgaWYgaXQncyBhIGZvbGRlciAqLwogICAgaWYgKGZvbGRlcikKCVNUUkNBVChmbmFtZSwgIjoiKTsKCiAgICAvKiBBcyB3ZSB1c2UgVW5peCBGaWxlIE5hbWUgZm9yIE1hY09TIFggY29udmVydCBpdCAqLwojaWZkZWYgVVNFX1VOSVhGSUxFTkFNRQogICAgLyogTmVlZCB0byBpbnNlcnQgbGVhZGluZyAvICovCiAgICAvKiBUT0RPOiBnZXQgdGhlIGFib3ZlIGNvZGUgdG8gdXNlIGRpcmVjdGx5IHRoZSAvICovCiAgICBTVFJDUFkoJnRlbXBvcmFyeVB0clsxXSwgZmlsZW5hbWVQdHIpOwogICAgdGVtcG9yYXJ5UHRyWzBdID0gJy8nOwogICAgU1RSQ1BZKGZpbGVuYW1lUHRyLCB0ZW1wb3JhcnlQdHIpOwogICAgewogICAgY2hhcgkqcDsKICAgIGZvciAocCA9IGZuYW1lOyAqcDsgcCsrKQoJaWYgKCpwID09ICc6JykKCSAgICAqcCA9ICcvJzsKICAgIH0KI2VuZGlmCgogICAgcmV0dXJuICh2aW1fc3Ryc2F2ZShmbmFtZSkpOwojZW5kaWYKfQoKI2lmIGRlZmluZWQoVVNFX0lNX0NPTlRST0wpIHx8IGRlZmluZWQoUFJPVE8pCi8qCiAqIElucHV0IE1ldGhvZCBDb250cm9sIGZ1bmN0aW9ucy4KICovCgovKgogKiBOb3RpZnkgY3Vyc29yIHBvc2l0aW9uIHRvIElNLgogKi8KICAgIHZvaWQKaW1fc2V0X3Bvc2l0aW9uKGludCByb3csIGludCBjb2wpCnsKICAgIC8qIFRPRE86IEltcGxlbWVudCBtZSEgKi8KfQoKLyoKICogU2V0IElNIHN0YXR1cyBvbiAoImFjdGl2ZSIgaXMgVFJVRSkgb3Igb2ZmICgiYWN0aXZlIiBpcyBGQUxTRSkuCiAqLwogICAgdm9pZAppbV9zZXRfYWN0aXZlKGludCBhY3RpdmUpCnsKICAgIEtleVNjcmlwdChhY3RpdmUgPyBzbUtleVN5c1NjcmlwdCA6IHNtS2V5Um9tYW4pOwp9CgovKgogKiBHZXQgSU0gc3RhdHVzLiAgV2hlbiBJTSBpcyBvbiwgcmV0dXJuIG5vdCAwLiAgRWxzZSByZXR1cm4gMC4KICovCiAgICBpbnQKaW1fZ2V0X3N0YXR1cyh2b2lkKQp7CiAgICBTSW50MzIgc2NyaXB0ID0gR2V0U2NyaXB0TWFuYWdlclZhcmlhYmxlKHNtS2V5U2NyaXB0KTsKICAgIHJldHVybiAoc2NyaXB0ICE9IHNtUm9tYW4KCSAgICAmJiBzY3JpcHQgPT0gR2V0U2NyaXB0TWFuYWdlclZhcmlhYmxlKHNtU3lzU2NyaXB0KSkgPyAxIDogMDsKfQojZW5kaWYgLyogZGVmaW5lZChVU0VfSU1fQ09OVFJPTCkgfHwgZGVmaW5lZChQUk9UTykgKi8K