PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+CjxodG1sPgoJPGhlYWQ+CgkJPHRpdGxlPlNtYXJ0IFBvaW50ZXIgUHJvZ3JhbW1pbmcgVGVjaG5pcXVlczwvdGl0bGU+CgkJPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSI+Cgk8L2hlYWQ+Cgk8Ym9keSB0ZXh0PSIjMDAwMDAwIiBiZ0NvbG9yPSIjZmZmZmZmIj4KCQk8aDE+PEEgaHJlZj0iLi4vLi4vaW5kZXguaHRtIj48SU1HIGhlaWdodD0iODYiIGFsdD0iYm9vc3QucG5nICg2ODk3IGJ5dGVzKSIgc3JjPSIuLi8uLi9ib29zdC5wbmciIHdpZHRoPSIyNzciIGFsaWduPSJtaWRkbGUiCgkJCQkJYm9yZGVyPSIwIj48L0E+U21hcnQgUG9pbnRlciBQcm9ncmFtbWluZyBUZWNobmlxdWVzPC9oMT4KCQk8cD48QSBocmVmPSIjaW5jb21wbGV0ZSI+VXNpbmcgaW5jb21wbGV0ZSBjbGFzc2VzIGZvciBpbXBsZW1lbnRhdGlvbiBoaWRpbmc8L0E+PGJyPgoJCQk8QSBocmVmPSIjcGltcGwiPlRoZSAiUGltcGwiIGlkaW9tPC9BPjxicj4KCQkJPEEgaHJlZj0iI2Fic3RyYWN0Ij5Vc2luZyBhYnN0cmFjdCBjbGFzc2VzIGZvciBpbXBsZW1lbnRhdGlvbiBoaWRpbmc8L0E+PGJyPgoJCQk8QSBocmVmPSIjcHJldmVudGluZ19kZWxldGUiPlByZXZlbnRpbmcgPGNvZGU+ZGVsZXRlIHB4LmdldCgpPC9jb2RlPjwvQT48YnI+CgkJCTxBIGhyZWY9IiNhcnJheSI+VXNpbmcgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byBob2xkIGEgcG9pbnRlciB0byBhbiBhcnJheTwvQT48YnI+CgkJCTxBIGhyZWY9IiNlbmNhcHN1bGF0aW9uIj5FbmNhcHN1bGF0aW5nIGFsbG9jYXRpb24gZGV0YWlscywgd3JhcHBpbmcgZmFjdG9yeSAKCQkJCWZ1bmN0aW9uczwvQT48YnI+CgkJCTxBIGhyZWY9IiNzdGF0aWMiPlVzaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gaG9sZCBhIHBvaW50ZXIgdG8gYSBzdGF0aWNhbGx5IAoJCQkJYWxsb2NhdGVkIG9iamVjdDwvQT48YnI+CgkJCTxBIGhyZWY9IiNjb20iPlVzaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gaG9sZCBhIHBvaW50ZXIgdG8gYSBDT00gb2JqZWN0PC9BPjxicj4KCQkJPEEgaHJlZj0iI2ludHJ1c2l2ZSI+VXNpbmcgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byBob2xkIGEgcG9pbnRlciB0byBhbiBvYmplY3QgCgkJCQl3aXRoIGFuIGVtYmVkZGVkIHJlZmVyZW5jZSBjb3VudDwvQT48YnI+CgkJCTxBIGhyZWY9IiNhbm90aGVyX3NwIj5Vc2luZyBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IHRvIGhvbGQgYW5vdGhlciBzaGFyZWQgCgkJCQlvd25lcnNoaXAgc21hcnQgcG9pbnRlcjwvQT48YnI+CgkJCTxBIGhyZWY9IiNmcm9tX3JhdyI+T2J0YWluaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gZnJvbSBhIHJhdyBwb2ludGVyPC9BPjxicj4KCQkJPEEgaHJlZj0iI2luX2NvbnN0cnVjdG9yIj5PYnRhaW5pbmcgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiAoPGNvZGU+d2Vha19wdHI8L2NvZGU+KSAKCQkJCXRvIDxjb2RlPnRoaXM8L2NvZGU+IGluIGEgY29uc3RydWN0b3I8L0E+PGJyPgoJCQk8QSBocmVmPSIjZnJvbV90aGlzIj5PYnRhaW5pbmcgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byA8Y29kZT50aGlzPC9jb2RlPjwvQT48YnI+CgkJCTxBIGhyZWY9IiNoYW5kbGUiPlVzaW5nIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGFzIGEgc21hcnQgY291bnRlZCBoYW5kbGU8L0E+PGJyPgoJCQk8QSBocmVmPSIjb25fYmxvY2tfZXhpdCI+VXNpbmcgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gZXhlY3V0ZSBjb2RlIG9uIGJsb2NrIAoJCQkJZXhpdDwvQT48YnI+CgkJCTxBIGhyZWY9IiNwdm9pZCI+VXNpbmcgPGNvZGU+c2hhcmVkX3B0ciZsdDt2b2lkJmd0OzwvY29kZT4gdG8gaG9sZCBhbiBhcmJpdHJhcnkgCgkJCQlvYmplY3Q8L0E+PGJyPgoJCQk8QSBocmVmPSIjZXh0cmFfZGF0YSI+QXNzb2NpYXRpbmcgYXJiaXRyYXJ5IGRhdGEgd2l0aCBoZXRlcm9nZW5lb3VzIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+CgkJCQlpbnN0YW5jZXM8L0E+PGJyPgoJCQk8QSBocmVmPSIjYXNfbG9jayI+VXNpbmcgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gYXMgYSBDb3B5Q29uc3RydWN0aWJsZSBtdXRleCBsb2NrPC9BPjxicj4KCQkJPEEgaHJlZj0iI3dyYXBwZXIiPlVzaW5nIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IHRvIHdyYXAgbWVtYmVyIGZ1bmN0aW9uIGNhbGxzPC9BPjxicj4KCQkJPEEgaHJlZj0iI2RlbGF5ZWQiPkRlbGF5ZWQgZGVhbGxvY2F0aW9uPC9BPjxicj4KCQkJPEEgaHJlZj0iI3dlYWtfd2l0aG91dF9zaGFyZWQiPldlYWsgcG9pbnRlcnMgdG8gb2JqZWN0cyBub3QgbWFuYWdlZCBieSBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+PC9BPjxicj4KCQk8L3A+CgkJPGgyPjxBIG5hbWU9ImluY29tcGxldGUiPlVzaW5nIGluY29tcGxldGUgY2xhc3NlcyBmb3IgaW1wbGVtZW50YXRpb24gaGlkaW5nPC9BPjwvaDI+CgkJPHA+QSBwcm92ZW4gdGVjaG5pcXVlICh0aGF0IHdvcmtzIGluIEMsIHRvbykgZm9yIHNlcGFyYXRpbmcgaW50ZXJmYWNlIGZyb20gCgkJCWltcGxlbWVudGF0aW9uIGlzIHRvIHVzZSBhIHBvaW50ZXIgdG8gYW4gaW5jb21wbGV0ZSBjbGFzcyBhcyBhbiBvcGFxdWUgaGFuZGxlOjwvcD4KCQk8cHJlPmNsYXNzIEZJTEU7CgpGSUxFICogZm9wZW4oY2hhciBjb25zdCAqIG5hbWUsIGNoYXIgY29uc3QgKiBtb2RlKTsKdm9pZCBmcmVhZChGSUxFICogZiwgdm9pZCAqIGRhdGEsIHNpemVfdCBzaXplKTsKdm9pZCBmY2xvc2UoRklMRSAqIGYpOwo8L3ByZT4KCQk8cD5JdCBpcyBwb3NzaWJsZSB0byBleHByZXNzIHRoZSBhYm92ZSBpbnRlcmZhY2UgdXNpbmcgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4sIAoJCQllbGltaW5hdGluZyB0aGUgbmVlZCB0byBtYW51YWxseSBjYWxsIDxjb2RlPmZjbG9zZTwvY29kZT46PC9wPgoJCTxwcmU+Y2xhc3MgRklMRTsKCnNoYXJlZF9wdHImbHQ7RklMRSZndDsgZm9wZW4oY2hhciBjb25zdCAqIG5hbWUsIGNoYXIgY29uc3QgKiBtb2RlKTsKdm9pZCBmcmVhZChzaGFyZWRfcHRyJmx0O0ZJTEUmZ3Q7IGYsIHZvaWQgKiBkYXRhLCBzaXplX3Qgc2l6ZSk7CjwvcHJlPgoJCTxwPlRoaXMgdGVjaG5pcXVlIHJlbGllcyBvbiA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPidzIGFiaWxpdHkgdG8gZXhlY3V0ZSBhIGN1c3RvbSAKCQkJZGVsZXRlciwgZWxpbWluYXRpbmcgdGhlIGV4cGxpY2l0IGNhbGwgdG8gPGNvZGU+ZmNsb3NlPC9jb2RlPiwgYW5kIG9uIHRoZSBmYWN0IAoJCQl0aGF0IDxjb2RlPnNoYXJlZF9wdHImbHQ7WCZndDs8L2NvZGU+IGNhbiBiZSBjb3BpZWQgYW5kIGRlc3Ryb3llZCB3aGVuIDxjb2RlPlg8L2NvZGU+CgkJCWlzIGluY29tcGxldGUuPC9wPgoJCTxoMj48QSBuYW1lPSJwaW1wbCI+VGhlICJQaW1wbCIgaWRpb208L0E+PC9oMj4KCQk8cD5BIEMrKyBzcGVjaWZpYyB2YXJpYXRpb24gb2YgdGhlIGluY29tcGxldGUgY2xhc3MgcGF0dGVybiBpcyB0aGUgIlBpbXBsIiBpZGlvbS4gCgkJCVRoZSBpbmNvbXBsZXRlIGNsYXNzIGlzIG5vdCBleHBvc2VkIHRvIHRoZSB1c2VyOyBpdCBpcyBoaWRkZW4gYmVoaW5kIGEgCgkJCWZvcndhcmRpbmcgZmFjYWRlLiA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiBjYW4gYmUgdXNlZCB0byBpbXBsZW1lbnQgYSAiUGltcGwiOjwvcD4KCQk8cHJlPi8vIGZpbGUuaHBwOgoKY2xhc3MgZmlsZQp7CnByaXZhdGU6CgogICAgY2xhc3MgaW1wbDsKICAgIHNoYXJlZF9wdHImbHQ7aW1wbCZndDsgcGltcGxfOwoKcHVibGljOgoKICAgIGZpbGUoY2hhciBjb25zdCAqIG5hbWUsIGNoYXIgY29uc3QgKiBtb2RlKTsKCiAgICAvLyBjb21waWxlciBnZW5lcmF0ZWQgbWVtYmVycyBhcmUgZmluZSBhbmQgdXNlZnVsCgogICAgdm9pZCByZWFkKHZvaWQgKiBkYXRhLCBzaXplX3Qgc2l6ZSk7Cn07CjwvcHJlPgoJCTxwcmU+Ly8gZmlsZS5jcHA6CgojaW5jbHVkZSAiZmlsZS5ocHAiCgpjbGFzcyBmaWxlOjppbXBsCnsKcHJpdmF0ZToKCiAgICBpbXBsKGltcGwgY29uc3QgJmFtcDspOwogICAgaW1wbCAmYW1wOyBvcGVyYXRvcj0oaW1wbCBjb25zdCAmYW1wOyk7CgogICAgLy8gcHJpdmF0ZSBkYXRhCgpwdWJsaWM6CgogICAgaW1wbChjaGFyIGNvbnN0ICogbmFtZSwgY2hhciBjb25zdCAqIG1vZGUpIHsgLi4uIH0KICAgIH5pbXBsKCkgeyAuLi4gfQogICAgdm9pZCByZWFkKHZvaWQgKiBkYXRhLCBzaXplX3Qgc2l6ZSkgeyAuLi4gfQp9OwoKZmlsZTo6ZmlsZShjaGFyIGNvbnN0ICogbmFtZSwgY2hhciBjb25zdCAqIG1vZGUpOiBwaW1wbF8obmV3IGltcGwobmFtZSwgbW9kZSkpCnsKfQoKdm9pZCBmaWxlOjpyZWFkKHZvaWQgKiBkYXRhLCBzaXplX3Qgc2l6ZSkKewogICAgcGltcGxfLSZndDtyZWFkKGRhdGEsIHNpemUpOwp9CjwvcHJlPgoJCTxwPlRoZSBrZXkgdGhpbmcgdG8gbm90ZSBoZXJlIGlzIHRoYXQgdGhlIGNvbXBpbGVyLWdlbmVyYXRlZCBjb3B5IGNvbnN0cnVjdG9yLCAKCQkJYXNzaWdubWVudCBvcGVyYXRvciwgYW5kIGRlc3RydWN0b3IgYWxsIGhhdmUgYSBzZW5zaWJsZSBtZWFuaW5nLiBBcyBhIHJlc3VsdCwgPGNvZGU+CgkJCQlmaWxlPC9jb2RlPiBpcyA8Y29kZT5Db3B5Q29uc3RydWN0aWJsZTwvY29kZT4gYW5kIDxjb2RlPkFzc2lnbmFibGU8L2NvZGU+LCAKCQkJYWxsb3dpbmcgaXRzIHVzZSBpbiBzdGFuZGFyZCBjb250YWluZXJzLjwvcD4KCQk8aDI+PEEgbmFtZT0iYWJzdHJhY3QiPlVzaW5nIGFic3RyYWN0IGNsYXNzZXMgZm9yIGltcGxlbWVudGF0aW9uIGhpZGluZzwvQT48L2gyPgoJCTxwPkFub3RoZXIgd2lkZWx5IHVzZWQgQysrIGlkaW9tIGZvciBzZXBhcmF0aW5nIGludGVmYWNlIGFuZCBpbXBsZW1lbnRhdGlvbiBpcyB0byAKCQkJdXNlIGFic3RyYWN0IGJhc2UgY2xhc3NlcyBhbmQgZmFjdG9yeSBmdW5jdGlvbnMuIFRoZSBhYnN0cmFjdCBjbGFzc2VzIGFyZSAKCQkJc29tZXRpbWVzIGNhbGxlZCAiaW50ZXJmYWNlcyIgYW5kIHRoZSBwYXR0ZXJuIGlzIGtub3duIGFzICJpbnRlcmZhY2UtYmFzZWQgCgkJCXByb2dyYW1taW5nIi4gQWdhaW4sIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGNhbiBiZSB1c2VkIGFzIHRoZSByZXR1cm4gdHlwZSBvZiAKCQkJdGhlIGZhY3RvcnkgZnVuY3Rpb25zOjwvcD4KCQk8cHJlPi8vIFguaHBwOgoKY2xhc3MgWAp7CnB1YmxpYzoKCiAgICB2aXJ0dWFsIHZvaWQgZigpID0gMDsKICAgIHZpcnR1YWwgdm9pZCBnKCkgPSAwOwoKcHJvdGVjdGVkOgoKICAgIH5YKCkge30KfTsKCnNoYXJlZF9wdHImbHQ7WCZndDsgY3JlYXRlWCgpOwo8L3ByZT4KCQk8cHJlPi0tIFguY3BwOgoKY2xhc3MgWF9pbXBsOiBwdWJsaWMgWAp7CnByaXZhdGU6CgogICAgWF9pbXBsKFhfaW1wbCBjb25zdCAmYW1wOyk7CiAgICBYX2ltcGwgJmFtcDsgb3BlcmF0b3I9KFhfaW1wbCBjb25zdCAmYW1wOyk7CgpwdWJsaWM6CgogICAgdmlydHVhbCB2b2lkIGYoKQogICAgewogICAgICAvLyAuLi4KICAgIH0KCiAgICB2aXJ0dWFsIHZvaWQgZygpCiAgICB7CiAgICAgIC8vIC4uLgogICAgfQp9OwoKc2hhcmVkX3B0ciZsdDtYJmd0OyBjcmVhdGVYKCkKewogICAgc2hhcmVkX3B0ciZsdDtYJmd0OyBweChuZXcgWF9pbXBsKTsKICAgIHJldHVybiBweDsKfQo8L3ByZT4KCQk8cD5BIGtleSBwcm9wZXJ0eSBvZiBzaGFyZWRfcHRyIGlzIHRoYXQgdGhlIGFsbG9jYXRpb24sIGNvbnN0cnVjdGlvbiwgZGVhbGxvY2F0aW9uLCAKCQkJYW5kIGRlc3RydWN0aW9uIGRldGFpbHMgYXJlIGNhcHR1cmVkIGF0IHRoZSBwb2ludCBvZiBjb25zdHJ1Y3Rpb24sIGluc2lkZSB0aGUgCgkJCWZhY3RvcnkgZnVuY3Rpb24uIE5vdGUgdGhlIHByb3RlY3RlZCBhbmQgbm9udmlydHVhbCBkZXN0cnVjdG9yIGluIHRoZSBleGFtcGxlIAoJCQlhYm92ZS4gVGhlIGNsaWVudCBjb2RlIGNhbm5vdCwgYW5kIGRvZXMgbm90IG5lZWQgdG8sIGRlbGV0ZSBhIHBvaW50ZXIgdG8gPGNvZGU+WDwvY29kZT47IAoJCQl0aGUgPGNvZGU+c2hhcmVkX3B0ciZsdDtYJmd0OzwvY29kZT4gaW5zdGFuY2UgcmV0dXJuZWQgZnJvbSA8Y29kZT5jcmVhdGVYPC9jb2RlPgoJCQl3aWxsIGNvcnJlY3RseSBjYWxsIDxjb2RlPn5YX2ltcGw8L2NvZGU+LjwvcD4KCQk8aDI+PEEgbmFtZT0icHJldmVudGluZ19kZWxldGUiPlByZXZlbnRpbmcgPGNvZGU+ZGVsZXRlIHB4LmdldCgpPC9jb2RlPjwvQT48L2gyPgoJCTxwPkl0IGlzIG9mdGVuIGRlc2lyYWJsZSB0byBwcmV2ZW50IGNsaWVudCBjb2RlIGZyb20gZGVsZXRpbmcgYSBwb2ludGVyIHRoYXQgaXMgCgkJCWJlaW5nIG1hbmFnZWQgYnkgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4uIFRoZSBwcmV2aW91cyB0ZWNobmlxdWUgc2hvd2VkIG9uZSAKCQkJcG9zc2libGUgYXBwcm9hY2gsIHVzaW5nIGEgcHJvdGVjdGVkIGRlc3RydWN0b3IuIEFub3RoZXIgYWx0ZXJuYXRpdmUgaXMgdG8gdXNlIAoJCQlhIHByaXZhdGUgZGVsZXRlcjo8L3A+CgkJPHByZT5jbGFzcyBYCnsKcHJpdmF0ZToKCiAgICB+WCgpOwoKICAgIGNsYXNzIGRlbGV0ZXI7CiAgICBmcmllbmQgY2xhc3MgZGVsZXRlcjsKCiAgICBjbGFzcyBkZWxldGVyCiAgICB7CiAgICBwdWJsaWM6CgogICAgICAgIHZvaWQgb3BlcmF0b3IoKShYICogcCkgeyBkZWxldGUgcDsgfQogICAgfTsKCnB1YmxpYzoKCiAgICBzdGF0aWMgc2hhcmVkX3B0ciZsdDtYJmd0OyBjcmVhdGUoKQogICAgewogICAgICAgIHNoYXJlZF9wdHImbHQ7WCZndDsgcHgobmV3IFgsIFg6OmRlbGV0ZXIoKSk7CiAgICAgICAgcmV0dXJuIHB4OwogICAgfQp9Owo8L3ByZT4KCQk8aDI+PEEgbmFtZT0iYXJyYXkiPlVzaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gaG9sZCBhIHBvaW50ZXIgdG8gYW4gYXJyYXk8L0E+PC9oMj4KCQk8cD5BIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGNhbiBiZSB1c2VkIHRvIGhvbGQgYSBwb2ludGVyIHRvIGFuIGFycmF5IGFsbG9jYXRlZCAKCQkJd2l0aCA8Y29kZT5uZXdbXTwvY29kZT46PC9wPgoJCTxwcmU+c2hhcmVkX3B0ciZsdDtYJmd0OyBweChuZXcgWFsxXSwgPEEgaHJlZj0iLi4vdXRpbGl0eS9jaGVja2VkX2RlbGV0ZS5odG1sIiA+Y2hlY2tlZF9hcnJheV9kZWxldGVyPC9BPiZsdDtYJmd0OygpKTsKPC9wcmU+CgkJPHA+Tm90ZSwgaG93ZXZlciwgdGhhdCA8Y29kZT48QSBocmVmPSJzaGFyZWRfYXJyYXkuaHRtIj5zaGFyZWRfYXJyYXk8L0E+PC9jb2RlPiBpcyAKCQkJb2Z0ZW4gcHJlZmVyYWJsZSwgaWYgdGhpcyBpcyBhbiBvcHRpb24uIEl0IGhhcyBhbiBhcnJheS1zcGVjaWZpYyBpbnRlcmZhY2UsIAoJCQl3aXRob3V0IDxjb2RlPm9wZXJhdG9yKjwvY29kZT4gYW5kIDxjb2RlPm9wZXJhdG9yLSZndDs8L2NvZGU+LCBhbmQgZG9lcyBub3QgCgkJCWFsbG93IHBvaW50ZXIgY29udmVyc2lvbnMuPC9wPgoJCTxoMj48QSBuYW1lPSJlbmNhcHN1bGF0aW9uIj5FbmNhcHN1bGF0aW5nIGFsbG9jYXRpb24gZGV0YWlscywgd3JhcHBpbmcgZmFjdG9yeSAKCQkJCWZ1bmN0aW9uczwvQT48L2gyPgoJCTxwPjxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGNhbiBiZSB1c2VkIGluIGNyZWF0aW5nIEMrKyB3cmFwcGVycyBvdmVyIGV4aXN0aW5nIEMgCgkJCXN0eWxlIGxpYnJhcnkgaW50ZXJmYWNlcyB0aGF0IHJldHVybiByYXcgcG9pbnRlcnMgZnJvbSB0aGVpciBmYWN0b3J5IGZ1bmN0aW9ucyAKCQkJdG8gZW5jYXBzdWxhdGUgYWxsb2NhdGlvbiBkZXRhaWxzLiBBcyBhbiBleGFtcGxlLCBjb25zaWRlciB0aGlzIGludGVyZmFjZSwgCgkJCXdoZXJlIDxjb2RlPkNyZWF0ZVg8L2NvZGU+IG1pZ2h0IGFsbG9jYXRlIDxjb2RlPlg8L2NvZGU+IGZyb20gaXRzIG93biBwcml2YXRlIAoJCQloZWFwLCA8Y29kZT5+WDwvY29kZT4gbWF5IGJlIGluYWNjZXNzaWJsZSwgb3IgPGNvZGU+WDwvY29kZT4gbWF5IGJlIGluY29tcGxldGU6PC9wPgoJCTxwcmU+WCAqIENyZWF0ZVgoKTsKdm9pZCBEZXN0cm95WChYICopOwo8L3ByZT4KCQk8cD5UaGUgb25seSB3YXkgdG8gcmVsaWFibHkgZGVzdHJveSBhIHBvaW50ZXIgcmV0dXJuZWQgYnkgPGNvZGU+Q3JlYXRlWDwvY29kZT4gaXMgCgkJCXRvIGNhbGwgPGNvZGU+RGVzdHJveVg8L2NvZGU+LjwvcD4KCQk8UD5IZXJlIGlzIGhvdyBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+LWJhc2VkIHdyYXBwZXIgbWF5IGxvb2sgbGlrZTo8L1A+CgkJPHByZT5zaGFyZWRfcHRyJmx0O1gmZ3Q7IGNyZWF0ZVgoKQp7CiAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4KENyZWF0ZVgoKSwgRGVzdHJveVgpOwogICAgcmV0dXJuIHB4Owp9CjwvcHJlPgoJCTxwPkNsaWVudCBjb2RlIHRoYXQgY2FsbHMgPGNvZGU+Y3JlYXRlWDwvY29kZT4gc3RpbGwgZG9lcyBub3QgbmVlZCB0byBrbm93IGhvdyB0aGUgCgkJCW9iamVjdCBoYXMgYmVlbiBhbGxvY2F0ZWQsIGJ1dCBub3cgdGhlIGRlc3RydWN0aW9uIGlzIGF1dG9tYXRpYy48L3A+CgkJPGgyPjxBIG5hbWU9InN0YXRpYyI+VXNpbmcgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byBob2xkIGEgcG9pbnRlciB0byBhIHN0YXRpY2FsbHkgCgkJCQlhbGxvY2F0ZWQgb2JqZWN0PC9BPjwvaDI+CgkJPHA+U29tZXRpbWVzIGl0IGlzIGRlc2lyYWJsZSB0byBjcmVhdGUgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byBhbiBhbHJlYWR5IAoJCQlleGlzdGluZyBvYmplY3QsIHNvIHRoYXQgdGhlIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGRvZXMgbm90IGF0dGVtcHQgdG8gCgkJCWRlc3Ryb3kgdGhlIG9iamVjdCB3aGVuIHRoZXJlIGFyZSBubyBtb3JlIHJlZmVyZW5jZXMgbGVmdC4gQXMgYW4gZXhhbXBsZSwgdGhlIAoJCQlmYWN0b3J5IGZ1bmN0aW9uOjwvcD4KCQk8cHJlPnNoYXJlZF9wdHImbHQ7WCZndDsgY3JlYXRlWCgpOwo8L3ByZT4KCQk8cD5pbiBjZXJ0YWluIHNpdHVhdGlvbnMgbWF5IG5lZWQgdG8gcmV0dXJuIGEgcG9pbnRlciB0byBhIHN0YXRpY2FsbHkgYWxsb2NhdGVkIDxjb2RlPlg8L2NvZGU+CgkJCWluc3RhbmNlLjwvcD4KCQk8UD5UaGUgc29sdXRpb24gaXMgdG8gdXNlIGEgY3VzdG9tIGRlbGV0ZXIgdGhhdCBkb2VzIG5vdGhpbmc6PC9QPgoJCTxwcmU+c3RydWN0IG51bGxfZGVsZXRlcgp7CiAgICB2b2lkIG9wZXJhdG9yKCkodm9pZCBjb25zdCAqKSBjb25zdAogICAgewogICAgfQp9OwoKc3RhdGljIFggeDsKCnNoYXJlZF9wdHImbHQ7WCZndDsgY3JlYXRlWCgpCnsKICAgIHNoYXJlZF9wdHImbHQ7WCZndDsgcHgoJmFtcDt4LCBudWxsX2RlbGV0ZXIoKSk7CiAgICByZXR1cm4gcHg7Cn0KPC9wcmU+CgkJPHA+VGhlIHNhbWUgdGVjaG5pcXVlIHdvcmtzIGZvciBhbnkgb2JqZWN0IGtub3duIHRvIG91dGxpdmUgdGhlIHBvaW50ZXIuPC9wPgoJCTxoMj48QSBuYW1lPSJjb20iPlVzaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gaG9sZCBhIHBvaW50ZXIgdG8gYSBDT00gT2JqZWN0PC9BPjwvaDI+CgkJPHA+QmFja2dyb3VuZDogQ09NIG9iamVjdHMgaGF2ZSBhbiBlbWJlZGRlZCByZWZlcmVuY2UgY291bnQgYW5kIHR3byBtZW1iZXIgCgkJCWZ1bmN0aW9ucyB0aGF0IG1hbmlwdWxhdGUgaXQuIDxjb2RlPkFkZFJlZigpPC9jb2RlPiBpbmNyZW1lbnRzIHRoZSBjb3VudC4gPGNvZGU+UmVsZWFzZSgpPC9jb2RlPgoJCQlkZWNyZW1lbnRzIHRoZSBjb3VudCBhbmQgZGVzdHJveXMgaXRzZWxmIHdoZW4gdGhlIGNvdW50IGRyb3BzIHRvIHplcm8uPC9wPgoJCTxQPkl0IGlzIHBvc3NpYmxlIHRvIGhvbGQgYSBwb2ludGVyIHRvIGEgQ09NIG9iamVjdCBpbiBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+OjwvUD4KCQk8cHJlPnNoYXJlZF9wdHImbHQ7SVdoYXRldmVyJmd0OyBtYWtlX3NoYXJlZF9mcm9tX0NPTShJV2hhdGV2ZXIgKiBwKQp7CiAgICBwLSZndDtBZGRSZWYoKTsKICAgIHNoYXJlZF9wdHImbHQ7SVdoYXRldmVyJmd0OyBwdyhwLCA8QSBocmVmPSIuLi9iaW5kL21lbV9mbi5odG1sIiA+bWVtX2ZuPC9BPigmYW1wO0lXaGF0ZXZlcjo6UmVsZWFzZSkpOwogICAgcmV0dXJuIHB3Owp9CjwvcHJlPgoJCTxwPk5vdGUsIGhvd2V2ZXIsIHRoYXQgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gY29waWVzIGNyZWF0ZWQgZnJvbSA8Y29kZT5wdzwvY29kZT4gd2lsbCAKCQkJbm90ICJyZWdpc3RlciIgaW4gdGhlIGVtYmVkZGVkIGNvdW50IG9mIHRoZSBDT00gb2JqZWN0OyB0aGV5IHdpbGwgc2hhcmUgdGhlIAoJCQlzaW5nbGUgcmVmZXJlbmNlIGNyZWF0ZWQgaW4gPGNvZGU+bWFrZV9zaGFyZWRfZnJvbV9DT008L2NvZGU+LiBXZWFrIHBvaW50ZXJzIAoJCQljcmVhdGVkIGZyb20gPGNvZGU+cHc8L2NvZGU+IHdpbGwgYmUgaW52YWxpZGF0ZWQgd2hlbiB0aGUgbGFzdCA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPgoJCQlpcyBkZXN0cm95ZWQsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgQ09NIG9iamVjdCBpdHNlbGYgaXMgc3RpbGwgYWxpdmUuPC9wPgoJCTxQPkFzIDxBIGhyZWY9Ii4uL2JpbmQvbWVtX2ZuLmh0bWwjUTMiPmV4cGxhaW5lZDwvQT4gaW4gdGhlIDxjb2RlPm1lbV9mbjwvY29kZT4gZG9jdW1lbnRhdGlvbiwgCgkJCXlvdSBuZWVkIHRvIDxBIGhyZWY9Ii4uL2JpbmQvbWVtX2ZuLmh0bWwjc3RkY2FsbCI+I2RlZmluZSAKCQkJCUJPT1NUX01FTV9GTl9FTkFCTEVfU1REQ0FMTDwvQT4gZmlyc3QuPC9QPgoJCTxoMj48QSBuYW1lPSJpbnRydXNpdmUiPlVzaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gaG9sZCBhIHBvaW50ZXIgdG8gYW4gb2JqZWN0IAoJCQkJd2l0aCBhbiBlbWJlZGRlZCByZWZlcmVuY2UgY291bnQ8L0E+PC9oMj4KCQk8cD5UaGlzIGlzIGEgZ2VuZXJhbGl6YXRpb24gb2YgdGhlIGFib3ZlIHRlY2huaXF1ZS4gVGhlIGV4YW1wbGUgYXNzdW1lcyB0aGF0IHRoZSAKCQkJb2JqZWN0IGltcGxlbWVudHMgdGhlIHR3byBmdW5jdGlvbnMgcmVxdWlyZWQgYnkgPGNvZGU+PEEgaHJlZj0iaW50cnVzaXZlX3B0ci5odG1sIj5pbnRydXNpdmVfcHRyPC9BPjwvY29kZT4sCgkJCTxjb2RlPmludHJ1c2l2ZV9wdHJfYWRkX3JlZjwvY29kZT4gYW5kIDxjb2RlPmludHJ1c2l2ZV9wdHJfcmVsZWFzZTwvY29kZT46PC9wPgoJCTxwcmU+dGVtcGxhdGUmbHQ7Y2xhc3MgVCZndDsgc3RydWN0IGludHJ1c2l2ZV9kZWxldGVyCnsKICAgIHZvaWQgb3BlcmF0b3IoKShUICogcCkKICAgIHsKICAgICAgICBpZihwKSBpbnRydXNpdmVfcHRyX3JlbGVhc2UocCk7CiAgICB9Cn07CgpzaGFyZWRfcHRyJmx0O1gmZ3Q7IG1ha2Vfc2hhcmVkX2Zyb21faW50cnVzaXZlKFggKiBwKQp7CiAgICBpZihwKSBpbnRydXNpdmVfcHRyX2FkZF9yZWYocCk7CiAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4KHAsIGludHJ1c2l2ZV9kZWxldGVyJmx0O1gmZ3Q7KCkpOwogICAgcmV0dXJuIHB4Owp9CjwvcHJlPgoJCTxoMj48QSBuYW1lPSJhbm90aGVyX3NwIj5Vc2luZyBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IHRvIGhvbGQgYW5vdGhlciBzaGFyZWQgCgkJCQlvd25lcnNoaXAgc21hcnQgcG9pbnRlcjwvQT48L2gyPgoJCTxwPk9uZSBvZiB0aGUgZGVzaWduIGdvYWxzIG9mIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGlzIHRvIGJlIHVzZWQgaW4gbGlicmFyeSAKCQkJaW50ZXJmYWNlcy4gSXQgaXMgcG9zc2libGUgdG8gZW5jb3VudGVyIGEgc2l0dWF0aW9uIHdoZXJlIGEgbGlicmFyeSB0YWtlcyBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+CgkJCWFyZ3VtZW50LCBidXQgdGhlIG9iamVjdCBhdCBoYW5kIGlzIGJlaW5nIG1hbmFnZWQgYnkgYSBkaWZmZXJlbnQgcmVmZXJlbmNlIAoJCQljb3VudGVkIG9yIGxpbmtlZCBzbWFydCBwb2ludGVyLjwvcD4KCQk8UD5JdCBpcyBwb3NzaWJsZSB0byBleHBsb2l0IDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+J3MgY3VzdG9tIGRlbGV0ZXIgZmVhdHVyZSB0byAKCQkJd3JhcCB0aGlzIGV4aXN0aW5nIHNtYXJ0IHBvaW50ZXIgYmVoaW5kIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gZmFjYWRlOjwvUD4KCQk8cHJlPnRlbXBsYXRlJmx0O2NsYXNzIFAmZ3Q7IHN0cnVjdCBzbWFydF9wb2ludGVyX2RlbGV0ZXIKewpwcml2YXRlOgoKICAgIFAgcF87CgpwdWJsaWM6CgogICAgc21hcnRfcG9pbnRlcl9kZWxldGVyKFAgY29uc3QgJmFtcDsgcCk6IHBfKHApCiAgICB7CiAgICB9CgogICAgdm9pZCBvcGVyYXRvcigpKHZvaWQgY29uc3QgKikKICAgIHsKICAgICAgICBwXy5yZXNldCgpOwogICAgfQogICAgCiAgICBQIGNvbnN0ICZhbXA7IGdldCgpIGNvbnN0CiAgICB7CiAgICAgICAgcmV0dXJuIHBfOwogICAgfQp9OwoKc2hhcmVkX3B0ciZsdDtYJmd0OyBtYWtlX3NoYXJlZF9mcm9tX2Fub3RoZXIoYW5vdGhlcl9wdHImbHQ7WCZndDsgcXgpCnsKICAgIHNoYXJlZF9wdHImbHQ7WCZndDsgcHgocXguZ2V0KCksIHNtYXJ0X3BvaW50ZXJfZGVsZXRlciZsdDsgYW5vdGhlcl9wdHImbHQ7WCZndDsgJmd0OyhxeCkpOwogICAgcmV0dXJuIHB4Owp9CjwvcHJlPgoJCTxwPk9uZSBzdWJ0bGUgcG9pbnQgaXMgdGhhdCBkZWxldGVycyBhcmUgbm90IGFsbG93ZWQgdG8gdGhyb3cgZXhjZXB0aW9ucywgYW5kIHRoZSAKCQkJYWJvdmUgZXhhbXBsZSBhcyB3cml0dGVuIGFzc3VtZXMgdGhhdCA8Y29kZT5wXy5yZXNldCgpPC9jb2RlPiBkb2Vzbid0IHRocm93LiBJZiAKCQkJdGhpcyBpcyBub3QgdGhlIGNhc2UsIDxjb2RlPnBfLnJlc2V0KCk8L2NvZGU+IHNob3VsZCBiZSB3cmFwcGVkIGluIGEgPGNvZGU+dHJ5IHt9IAoJCQkJY2F0Y2goLi4uKSB7fTwvY29kZT4gYmxvY2sgdGhhdCBpZ25vcmVzIGV4Y2VwdGlvbnMuIEluIHRoZSAodXN1YWxseSAKCQkJdW5saWtlbHkpIGV2ZW50IHdoZW4gYW4gZXhjZXB0aW9uIGlzIHRocm93biBhbmQgaWdub3JlZCwgPGNvZGU+cF88L2NvZGU+IHdpbGwgCgkJCWJlIHJlbGVhc2VkIHdoZW4gdGhlIGxpZmV0aW1lIG9mIHRoZSBkZWxldGVyIGVuZHMuIFRoaXMgaGFwcGVucyB3aGVuIGFsbCAKCQkJcmVmZXJlbmNlcywgaW5jbHVkaW5nIHdlYWsgcG9pbnRlcnMsIGFyZSBkZXN0cm95ZWQgb3IgcmVzZXQuPC9wPgoJCTxQPkFub3RoZXIgdHdpc3QgaXMgdGhhdCBpdCBpcyBwb3NzaWJsZSwgZ2l2ZW4gdGhlIGFib3ZlIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGluc3RhbmNlLCAKCQkJdG8gcmVjb3ZlciB0aGUgb3JpZ2luYWwgc21hcnQgcG9pbnRlciwgdXNpbmcgPGNvZGU+PEEgaHJlZj0ic2hhcmVkX3B0ci5odG0jZ2V0X2RlbGV0ZXIiPgoJCQkJCWdldF9kZWxldGVyPC9BPjwvY29kZT46PC9QPgoJCTxwcmU+dm9pZCBleHRyYWN0X2Fub3RoZXJfZnJvbV9zaGFyZWQoc2hhcmVkX3B0ciZsdDtYJmd0OyBweCkKewogICAgdHlwZWRlZiBzbWFydF9wb2ludGVyX2RlbGV0ZXImbHQ7IGFub3RoZXJfcHRyJmx0O1gmZ3Q7ICZndDsgZGVsZXRlcjsKCiAgICBpZihkZWxldGVyIGNvbnN0ICogcGQgPSBnZXRfZGVsZXRlciZsdDtkZWxldGVyJmd0OyhweCkpCiAgICB7CiAgICAgICAgYW5vdGhlcl9wdHImbHQ7WCZndDsgcXggPSBwZC0mZ3Q7Z2V0KCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy8gbm90IG9uZSBvZiBvdXJzCiAgICB9Cn0KPC9wcmU+CgkJPGgyPjxBIG5hbWU9ImZyb21fcmF3Ij5PYnRhaW5pbmcgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiBmcm9tIGEgcmF3IHBvaW50ZXI8L0E+PC9oMj4KCQk8cD5Tb21ldGltZXMgaXQgaXMgbmVjZXNzYXJ5IHRvIG9idGFpbiBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGdpdmVuIGEgcmF3IAoJCQlwb2ludGVyIHRvIGFuIG9iamVjdCB0aGF0IGlzIGFscmVhZHkgbWFuYWdlZCBieSBhbm90aGVyIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IAoJCQlpbnN0YW5jZS4gRXhhbXBsZTo8L3A+CgkJPHByZT52b2lkIGYoWCAqIHApCnsKICAgIHNoYXJlZF9wdHImbHQ7WCZndDsgcHgoPGk+Pz8/PC9pPik7Cn0KPC9wcmU+CgkJPHA+SW5zaWRlIDxjb2RlPmY8L2NvZGU+LCB3ZSdkIGxpa2UgdG8gY3JlYXRlIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gPGNvZGU+KnA8L2NvZGU+LjwvcD4KCQk8UD5JbiB0aGUgZ2VuZXJhbCBjYXNlLCB0aGlzIHByb2JsZW0gaGFzIG5vIHNvbHV0aW9uLiBPbmUgYXBwcm9hY2ggaXMgdG8gbW9kaWZ5IDxjb2RlPmY8L2NvZGU+CgkJCXRvIHRha2UgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiwgaWYgcG9zc2libGU6PC9QPgoJCTxwcmU+dm9pZCBmKHNoYXJlZF9wdHImbHQ7WCZndDsgcHgpOwo8L3ByZT4KCQk8cD5UaGUgc2FtZSB0cmFuc2Zvcm1hdGlvbiBjYW4gYmUgdXNlZCBmb3Igbm9udmlydHVhbCBtZW1iZXIgZnVuY3Rpb25zLCB0byBjb252ZXJ0IAoJCQl0aGUgaW1wbGljaXQgPGNvZGU+dGhpczwvY29kZT46PC9wPgoJCTxwcmU+dm9pZCBYOjpmKGludCBtKTsKPC9wcmU+CgkJPHA+d291bGQgYmVjb21lIGEgZnJlZSBmdW5jdGlvbiB3aXRoIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gZmlyc3QgYXJndW1lbnQ6PC9wPgoJCTxwcmU+dm9pZCBmKHNoYXJlZF9wdHImbHQ7WCZndDsgdGhpc18sIGludCBtKTsKPC9wcmU+CgkJPHA+SWYgPGNvZGU+ZjwvY29kZT4gY2Fubm90IGJlIGNoYW5nZWQsIGJ1dCA8Y29kZT5YPC9jb2RlPiB1c2VzIGludHJ1c2l2ZSBjb3VudGluZywgCgkJCXVzZSA8Y29kZT48QSBocmVmPSIjaW50cnVzaXZlIj5tYWtlX3NoYXJlZF9mcm9tX2ludHJ1c2l2ZTwvQT48L2NvZGU+IGRlc2NyaWJlZCAKCQkJYWJvdmUuIE9yLCBpZiBpdCdzIGtub3duIHRoYXQgdGhlIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGNyZWF0ZWQgaW4gPGNvZGU+ZjwvY29kZT4KCQkJd2lsbCBuZXZlciBvdXRsaXZlIHRoZSBvYmplY3QsIHVzZSA8QSBocmVmPSIjc3RhdGljIj5hIG51bGwgZGVsZXRlcjwvQT4uPC9wPgoJCTxoMj48QSBuYW1lPSJpbl9jb25zdHJ1Y3RvciI+T2J0YWluaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gKDxjb2RlPndlYWtfcHRyPC9jb2RlPikgCgkJCQl0byA8Y29kZT50aGlzPC9jb2RlPiBpbiBhIGNvbnN0cnVjdG9yPC9BPjwvaDI+CgkJPHA+U29tZSBkZXNpZ25zIHJlcXVpcmUgb2JqZWN0cyB0byByZWdpc3RlciB0aGVtc2VsdmVzIG9uIGNvbnN0cnVjdGlvbiB3aXRoIGEgCgkJCWNlbnRyYWwgYXV0aG9yaXR5LiBXaGVuIHRoZSByZWdpc3RyYXRpb24gcm91dGluZXMgdGFrZSBhIHNoYXJlZF9wdHIsIHRoaXMgbGVhZHMgCgkJCXRvIHRoZSBxdWVzdGlvbiBob3cgY291bGQgYSBjb25zdHJ1Y3RvciBvYnRhaW4gYSBzaGFyZWRfcHRyIHRvIHRoaXM6PC9wPgoJCTxwcmU+Y2xhc3MgWAp7CnB1YmxpYzoKCiAgICBYKCkKICAgIHsKICAgICAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHRoaXNfKDxpPj8/PzwvaT4pOwogICAgfQp9Owo8L3ByZT4KCQk8cD5JbiB0aGUgZ2VuZXJhbCBjYXNlLCB0aGUgcHJvYmxlbSBjYW5ub3QgYmUgc29sdmVkLiBUaGUgPGNvZGU+WDwvY29kZT4gaW5zdGFuY2UgCgkJCWJlaW5nIGNvbnN0cnVjdGVkIGNhbiBiZSBhbiBhdXRvbWF0aWMgdmFyaWFibGUgb3IgYSBzdGF0aWMgdmFyaWFibGU7IGl0IGNhbiBiZSAKCQkJY3JlYXRlZCBvbiB0aGUgaGVhcDo8L3A+CgkJPHByZT5zaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4KG5ldyBYKTs8L3ByZT4KCQk8UD5idXQgYXQgY29uc3RydWN0aW9uIHRpbWUsIDxjb2RlPnB4PC9jb2RlPiBkb2VzIG5vdCBleGlzdCB5ZXQsIGFuZCBpdCBpcyAKCQkJaW1wb3NzaWJsZSB0byBjcmVhdGUgYW5vdGhlciA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiBpbnN0YW5jZSB0aGF0IHNoYXJlcyAKCQkJb3duZXJzaGlwIHdpdGggaXQuPC9QPgoJCTxQPkRlcGVuZGluZyBvbiBjb250ZXh0LCBpZiB0aGUgaW5uZXIgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gPGNvZGU+dGhpc188L2NvZGU+IGRvZXNuJ3QgCgkJCW5lZWQgdG8ga2VlcCB0aGUgb2JqZWN0IGFsaXZlLCB1c2UgYSA8Y29kZT5udWxsX2RlbGV0ZXI8L2NvZGU+IGFzIGV4cGxhaW5lZCA8QSBocmVmPSIjc3RhdGljIj4KCQkJCWhlcmU8L0E+IGFuZCA8QSBocmVmPSIjd2Vha193aXRob3V0X3NoYXJlZCI+aGVyZTwvQT4uIElmIDxjb2RlPlg8L2NvZGU+IGlzIAoJCQlzdXBwb3NlZCB0byBhbHdheXMgbGl2ZSBvbiB0aGUgaGVhcCwgYW5kIGJlIG1hbmFnZWQgYnkgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiwgCgkJCXVzZSBhIHN0YXRpYyBmYWN0b3J5IGZ1bmN0aW9uOjwvUD4KCQk8cHJlPmNsYXNzIFgKewpwcml2YXRlOgoKICAgIFgoKSB7IC4uLiB9CgpwdWJsaWM6CgogICAgc3RhdGljIHNoYXJlZF9wdHImbHQ7WCZndDsgY3JlYXRlKCkKICAgIHsKICAgICAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4KG5ldyBYKTsKICAgICAgICAvLyB1c2UgcHggYXMgJ3RoaXNfJwogICAgICAgIHJldHVybiBweDsKICAgIH0KfTsKPC9wcmU+CgkJPGgyPjxBIG5hbWU9ImZyb21fdGhpcyI+T2J0YWluaW5nIGEgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gdG8gPGNvZGU+dGhpczwvY29kZT48L0E+PC9oMj4KCQk8cD5Tb21ldGltZXMgaXQgaXMgbmVlZGVkIHRvIG9idGFpbiBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGZyb20gPGNvZGU+dGhpczwvY29kZT4KCQkJaW4gYSB2aXJ0dWFsIG1lbWJlciBmdW5jdGlvbiB1bmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IDxjb2RlPnRoaXM8L2NvZGU+IGlzIAoJCQlhbHJlYWR5IG1hbmFnZWQgYnkgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPi4gVGhlIHRyYW5zZm9ybWF0aW9ucyA8QSBocmVmPSIjZnJvbV9yYXciPgoJCQkJZGVzY3JpYmVkIGluIHRoZSBwcmV2aW91cyB0ZWNobmlxdWU8L0E+IGNhbm5vdCBiZSBhcHBsaWVkLjwvcD4KCQk8UD5BIHR5cGljYWwgZXhhbXBsZTo8L1A+CgkJPHByZT5jbGFzcyBYCnsKcHVibGljOgoKICAgIHZpcnR1YWwgdm9pZCBmKCkgPSAwOwoKcHJvdGVjdGVkOgoKICAgIH5YKCkge30KfTsKCmNsYXNzIFkKewpwdWJsaWM6CgogICAgdmlydHVhbCBzaGFyZWRfcHRyJmx0O1gmZ3Q7IGdldFgoKSA9IDA7Cgpwcm90ZWN0ZWQ6CgogICAgflkoKSB7fQp9OwoKLy8gLS0KCmNsYXNzIGltcGw6IHB1YmxpYyBYLCBwdWJsaWMgWQp7CnB1YmxpYzoKCiAgICBpbXBsKCkgeyAuLi4gfQoKICAgIHZpcnR1YWwgdm9pZCBmKCkgeyAuLi4gfQoKICAgIHZpcnR1YWwgc2hhcmVkX3B0ciZsdDtYJmd0OyBnZXRYKCkKICAgIHsKICAgICAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4KDxpPj8/PzwvaT4pOwogICAgICAgIHJldHVybiBweDsKICAgIH0KfTsKPC9wcmU+CgkJPHA+VGhlIHNvbHV0aW9uIGlzIHRvIGtlZXAgYSB3ZWFrIHBvaW50ZXIgdG8gPGNvZGU+dGhpczwvY29kZT4gYXMgYSBtZW1iZXIgaW4gPGNvZGU+aW1wbDwvY29kZT46PC9wPgoJCTxwcmU+Y2xhc3MgaW1wbDogcHVibGljIFgsIHB1YmxpYyBZCnsKcHJpdmF0ZToKCiAgICB3ZWFrX3B0ciZsdDtpbXBsJmd0OyB3ZWFrX3RoaXM7CgogICAgaW1wbChpbXBsIGNvbnN0ICZhbXA7KTsKICAgIGltcGwgJmFtcDsgb3BlcmF0b3I9KGltcGwgY29uc3QgJmFtcDspOwoKICAgIGltcGwoKSB7IC4uLiB9CgpwdWJsaWM6CgogICAgc3RhdGljIHNoYXJlZF9wdHImbHQ7aW1wbCZndDsgY3JlYXRlKCkKICAgIHsKICAgICAgICBzaGFyZWRfcHRyJmx0O2ltcGwmZ3Q7IHBpKG5ldyBpbXBsKTsKICAgICAgICBwaS0mZ3Q7d2Vha190aGlzID0gcGk7CiAgICAgICAgcmV0dXJuIHBpOwogICAgfQoKICAgIHZpcnR1YWwgdm9pZCBmKCkgeyAuLi4gfQoKICAgIHZpcnR1YWwgc2hhcmVkX3B0ciZsdDtYJmd0OyBnZXRYKCkKICAgIHsKICAgICAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4KHdlYWtfdGhpcyk7CiAgICAgICAgcmV0dXJuIHB4OwogICAgfQp9Owo8L3ByZT4KCQk8cD5UaGUgbGlicmFyeSBub3cgaW5jbHVkZXMgYSBoZWxwZXIgY2xhc3MgdGVtcGxhdGUgPGNvZGU+PEEgaHJlZj0iZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMuaHRtbCI+CgkJCQkJZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8L0E+PC9jb2RlPiB0aGF0IGNhbiBiZSB1c2VkIHRvIGVuY2Fwc3VsYXRlIHRoZSAKCQkJc29sdXRpb246PC9wPgoJCTxwcmU+Y2xhc3MgaW1wbDogcHVibGljIFgsIHB1YmxpYyBZLCBwdWJsaWMgZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMmbHQ7aW1wbCZndDsKewpwdWJsaWM6CgogICAgaW1wbChpbXBsIGNvbnN0ICZhbXA7KTsKICAgIGltcGwgJmFtcDsgb3BlcmF0b3I9KGltcGwgY29uc3QgJmFtcDspOwoKcHVibGljOgoKICAgIHZpcnR1YWwgdm9pZCBmKCkgeyAuLi4gfQoKICAgIHZpcnR1YWwgc2hhcmVkX3B0ciZsdDtYJmd0OyBnZXRYKCkKICAgIHsKICAgICAgICByZXR1cm4gc2hhcmVkX2Zyb21fdGhpcygpOwogICAgfQp9CjwvcHJlPgoJCTxwPk5vdGUgdGhhdCB5b3Ugbm8gbG9uZ2VyIG5lZWQgdG8gbWFudWFsbHkgaW5pdGlhbGl6ZSB0aGUgPGNvZGU+d2Vha19wdHI8L2NvZGU+IG1lbWJlciAKCQkJaW4gPGNvZGU+PEEgaHJlZj0iZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMuaHRtbCI+ZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8L0E+PC9jb2RlPi4gCgkJCUNvbnN0cnVjdGluZyBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IHRvIDxjb2RlPmltcGw8L2NvZGU+IHRha2VzIGNhcmUgb2YgdGhhdC48L3A+CgkJPGgyPjxBIG5hbWU9ImhhbmRsZSI+VXNpbmcgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gYXMgYSBzbWFydCBjb3VudGVkIGhhbmRsZTwvQT48L2gyPgoJCTxwPlNvbWUgbGlicmFyeSBpbnRlcmZhY2VzIHVzZSBvcGFxdWUgaGFuZGxlcywgYSB2YXJpYXRpb24gb2YgdGhlIDxBIGhyZWY9IiNpbmNvbXBsZXRlIj4KCQkJCWluY29tcGxldGUgY2xhc3MgdGVjaG5pcXVlPC9BPiBkZXNjcmliZWQgYWJvdmUuIEFuIGV4YW1wbGU6PC9wPgoJCTxwcmU+dHlwZWRlZiB2b2lkICogSEFORExFOwpIQU5ETEUgQ3JlYXRlUHJvY2VzcygpOwp2b2lkIENsb3NlSGFuZGxlKEhBTkRMRSk7CjwvcHJlPgoJCTxwPkluc3RlYWQgb2YgYSByYXcgcG9pbnRlciwgaXQgaXMgcG9zc2libGUgdG8gdXNlIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGFzIHRoZSAKCQkJaGFuZGxlIGFuZCBnZXQgcmVmZXJlbmNlIGNvdW50aW5nIGFuZCBhdXRvbWF0aWMgcmVzb3VyY2UgbWFuYWdlbWVudCBmb3IgZnJlZTo8L3A+CgkJPHByZT50eXBlZGVmIHNoYXJlZF9wdHImbHQ7dm9pZCZndDsgaGFuZGxlOwoKaGFuZGxlIGNyZWF0ZVByb2Nlc3MoKQp7CiAgICBzaGFyZWRfcHRyJmx0O3ZvaWQmZ3Q7IHB2KENyZWF0ZVByb2Nlc3MoKSwgQ2xvc2VIYW5kbGUpOwogICAgcmV0dXJuIHB2Owp9CjwvcHJlPgoJCTxoMj48QSBuYW1lPSJvbl9ibG9ja19leGl0Ij5Vc2luZyA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byBleGVjdXRlIGNvZGUgb24gYmxvY2sgZXhpdDwvQT48L2gyPgoJCTxwPjxjb2RlPnNoYXJlZF9wdHImbHQ7dm9pZCZndDs8L2NvZGU+IGNhbiBhdXRvbWF0aWNhbGx5IGV4ZWN1dGUgY2xlYW51cCBjb2RlIHdoZW4gCgkJCWNvbnRyb2wgbGVhdmVzIGEgc2NvcGUuPC9wPgoJCTxVTD4KCQkJPExJPgoJCQkJRXhlY3V0aW5nIDxjb2RlPmYocCk8L2NvZGU+LCB3aGVyZSA8Y29kZT5wPC9jb2RlPiBpcyBhIHBvaW50ZXI6PC9MST48L1VMPgoJCTxwcmU+ICAgIHNoYXJlZF9wdHImbHQ7dm9pZCZndDsgZ3VhcmQocCwgZik7CjwvcHJlPgoJCTxVTD4KCQkJPExJPgoJCQkJRXhlY3V0aW5nIGFyYml0cmFyeSBjb2RlOiA8Y29kZT5mKHgsIHkpPC9jb2RlPjo8L0xJPjwvVUw+CgkJPHByZT4gICAgc2hhcmVkX3B0ciZsdDt2b2lkJmd0OyBndWFyZChzdGF0aWNfY2FzdCZsdDt2b2lkKiZndDsoMCksIDxBIGhyZWY9Ii4uL2JpbmQvYmluZC5odG1sIiA+YmluZDwvQT4oZiwgeCwgeSkpOwo8L3ByZT4KCQk8UD5Gb3IgYSBtb3JlIHRob3JvdWdoIHRyZWF0bWVudCwgc2VlIHRoZSBhcnRpY2xlICJTaW1wbGlmeSBZb3VyIEV4Y2VwdGlvbi1TYWZlIAoJCQlDb2RlIiBieSBBbmRyZWkgQWxleGFuZHJlc2N1IGFuZCBQZXRydSBNYXJnaW5lYW4sIGF2YWlsYWJsZSBvbmxpbmUgYXQgPEEgaHJlZj0iaHR0cDovL3d3dy5jdWouY29tL2V4cGVydHMvMTgxMi9hbGV4YW5kci5odG0/dG9waWM9ZXhwZXJ0cyI+CgkJCQlodHRwOi8vd3d3LmN1ai5jb20vZXhwZXJ0cy8xODEyL2FsZXhhbmRyLmh0bT90b3BpYz1leHBlcnRzPC9BPi48L1A+CgkJPGgyPjxBIG5hbWU9InB2b2lkIj5Vc2luZyA8Y29kZT5zaGFyZWRfcHRyJmx0O3ZvaWQmZ3Q7PC9jb2RlPiB0byBob2xkIGFuIGFyYml0cmFyeSAKCQkJCW9iamVjdDwvQT48L2gyPgoJCTxwPjxjb2RlPnNoYXJlZF9wdHImbHQ7dm9pZCZndDs8L2NvZGU+IGNhbiBhY3QgYXMgYSBnZW5lcmljIG9iamVjdCBwb2ludGVyIHNpbWlsYXIgCgkJCXRvIDxjb2RlPnZvaWQqPC9jb2RlPi4gV2hlbiBhIDxjb2RlPnNoYXJlZF9wdHImbHQ7dm9pZCZndDs8L2NvZGU+IGluc3RhbmNlIAoJCQljb25zdHJ1Y3RlZCBhczo8L3A+CgkJPHByZT4gICAgc2hhcmVkX3B0ciZsdDt2b2lkJmd0OyBwdihuZXcgWCk7CjwvcHJlPgoJCTxwPmlzIGRlc3Ryb3llZCwgaXQgd2lsbCBjb3JyZWN0bHkgZGlzcG9zZSBvZiB0aGUgPGNvZGU+WDwvY29kZT4gb2JqZWN0IGJ5IAoJCQlleGVjdXRpbmcgPGNvZGU+flg8L2NvZGU+LjwvcD4KCQk8cD5UaGlzIHByb3BlcnkgY2FuIGJlIHVzZWQgaW4gbXVjaCB0aGUgc2FtZSBtYW5uZXIgYXMgYSByYXcgPGNvZGU+dm9pZCo8L2NvZGU+IGlzIAoJCQl1c2VkIHRvIHRlbXBvcmFyaWx5IHN0cmlwIHR5cGUgaW5mb3JtYXRpb24gZnJvbSBhbiBvYmplY3QgcG9pbnRlci4gQSA8Y29kZT5zaGFyZWRfcHRyJmx0O3ZvaWQmZ3Q7PC9jb2RlPgoJCQljYW4gbGF0ZXIgYmUgY2FzdCBiYWNrIHRvIHRoZSBjb3JyZWN0IHR5cGUgYnkgdXNpbmcgPGNvZGU+PEEgaHJlZj0ic2hhcmVkX3B0ci5odG0jc3RhdGljX3BvaW50ZXJfY2FzdCI+CgkJCQkJc3RhdGljX3BvaW50ZXJfY2FzdDwvQT48L2NvZGU+LjwvcD4KCQk8aDI+PEEgbmFtZT0iZXh0cmFfZGF0YSI+QXNzb2NpYXRpbmcgYXJiaXRyYXJ5IGRhdGEgd2l0aCBoZXRlcm9nZW5lb3VzIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+CgkJCQlpbnN0YW5jZXM8L0E+PC9oMj4KCQk8cD48Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiBhbmQgPGNvZGU+d2Vha19wdHI8L2NvZGU+IHN1cHBvcnQgPGNvZGU+b3BlcmF0b3ImbHQ7PC9jb2RlPgoJCQljb21wYXJpc29ucyByZXF1aXJlZCBieSBzdGFuZGFyZCBhc3NvY2lhdGl2ZSBjb250YWluZXJzIHN1Y2ggYXMgPGNvZGU+c3RkOjptYXA8L2NvZGU+LiAKCQkJVGhpcyBjYW4gYmUgdXNlZCB0byBub24taW50cnVzaXZlbHkgYXNzb2NpYXRlIGFyYml0cmFyeSBkYXRhIHdpdGggb2JqZWN0cyAKCQkJbWFuYWdlZCBieSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPjo8L3A+CgkJPHByZT50eXBlZGVmIGludCBEYXRhOwoKc3RkOjptYXAmbHQ7IHNoYXJlZF9wdHImbHQ7dm9pZCZndDssIERhdGEgJmd0OyB1c2VyRGF0YTsKLy8gb3Igc3RkOjptYXAmbHQ7IHdlYWtfcHRyJmx0O3ZvaWQmZ3Q7LCBEYXRhICZndDsgdXNlckRhdGE7IHRvIG5vdCBhZmZlY3QgdGhlIGxpZmV0aW1lCgpzaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4KG5ldyBYKTsKc2hhcmVkX3B0ciZsdDtpbnQmZ3Q7IHBpKG5ldyBpbnQoMykpOwoKdXNlckRhdGFbcHhdID0gNDI7CnVzZXJEYXRhW3BpXSA9IDkxOwo8L3ByZT4KCQk8aDI+PEEgbmFtZT0iYXNfbG9jayI+VXNpbmcgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gYXMgYSBDb3B5Q29uc3RydWN0aWJsZSBtdXRleCBsb2NrPC9BPjwvaDI+CgkJPHA+U29tZXRpbWVzIGl0J3MgbmVjZXNzYXJ5IHRvIHJldHVybiBhIG11dGV4IGxvY2sgZnJvbSBhIGZ1bmN0aW9uLCBhbmQgYSAKCQkJbm9uY29weWFibGUgbG9jayBjYW5ub3QgYmUgcmV0dXJuZWQgYnkgdmFsdWUuIEl0IGlzIHBvc3NpYmxlIHRvIHVzZSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPgoJCQlhcyBhIG11dGV4IGxvY2s6PC9wPgoJCTxwcmU+Y2xhc3MgbXV0ZXgKewpwdWJsaWM6CgogICAgdm9pZCBsb2NrKCk7CiAgICB2b2lkIHVubG9jaygpOwp9OwoKc2hhcmVkX3B0ciZsdDttdXRleCZndDsgbG9jayhtdXRleCAmYW1wOyBtKQp7CiAgICBtLmxvY2soKTsKICAgIHJldHVybiBzaGFyZWRfcHRyJmx0O211dGV4Jmd0OygmYW1wO20sIG1lbV9mbigmYW1wO211dGV4Ojp1bmxvY2spKTsKfQo8L3ByZT4KCQk8cD5CZXR0ZXIgeWV0LCB0aGUgPGNvZGU+c2hhcmVkX3B0cjwvY29kZT4gaW5zdGFuY2UgYWN0aW5nIGFzIGEgbG9jayBjYW4gYmUgCgkJCWVuY2Fwc3VsYXRlZCBpbiBhIGRlZGljYXRlZCA8Y29kZT5zaGFyZWRfbG9jazwvY29kZT4gY2xhc3M6PC9wPgoJCTxwcmU+Y2xhc3Mgc2hhcmVkX2xvY2sKewpwcml2YXRlOgoKICAgIHNoYXJlZF9wdHImbHQ7dm9pZCZndDsgcHY7CgpwdWJsaWM6CgogICAgdGVtcGxhdGUmbHQ7Y2xhc3MgTXV0ZXgmZ3Q7IGV4cGxpY2l0IHNoYXJlZF9sb2NrKE11dGV4ICZhbXA7IG0pOiBwdigobS5sb2NrKCksICZhbXA7bSksIG1lbV9mbigmYW1wO011dGV4Ojp1bmxvY2spKSB7fQp9Owo8L3ByZT4KCQk8cD48Y29kZT5zaGFyZWRfbG9jazwvY29kZT4gY2FuIG5vdyBiZSB1c2VkIGFzOjwvcD4KCQk8cHJlPiAgICBzaGFyZWRfbG9jayBsb2NrKG0pOwo8L3ByZT4KCQk8cD5Ob3RlIHRoYXQgPGNvZGU+c2hhcmVkX2xvY2s8L2NvZGU+IGlzIG5vdCB0ZW1wbGF0ZWQgb24gdGhlIG11dGV4IHR5cGUsIHRoYW5rcyB0byA8Y29kZT4KCQkJCXNoYXJlZF9wdHImbHQ7dm9pZCZndDs8L2NvZGU+J3MgYWJpbGl0eSB0byBoaWRlIHR5cGUgaW5mb3JtYXRpb24uPC9wPgoJCTxoMj48QSBuYW1lPSJ3cmFwcGVyIj5Vc2luZyA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byB3cmFwIG1lbWJlciBmdW5jdGlvbiBjYWxsczwvQT48L2gyPgoJCTxwPjxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+IGltcGxlbWVudHMgdGhlIG93bmVyc2hpcCBzZW1hbnRpY3MgcmVxdWlyZWQgZnJvbSB0aGUgPGNvZGU+V3JhcDwvY29kZT4vPGNvZGU+Q2FsbFByb3h5PC9jb2RlPgoJCQlzY2hlbWUgZGVzY3JpYmVkIGluIEJqYXJuZSBTdHJvdXN0cnVwJ3MgYXJ0aWNsZSAiV3JhcHBpbmcgQysrIE1lbWJlciBGdW5jdGlvbiAKCQkJQ2FsbHMiIChhdmFpbGFibGUgb25saW5lIGF0IDxBIGhyZWY9Imh0dHA6Ly93d3cucmVzZWFyY2guYXR0LmNvbS9+YnMvd3JhcHBlci5wZGYiPmh0dHA6Ly93d3cucmVzZWFyY2guYXR0LmNvbS9+YnMvd3JhcHBlci5wZGY8L0E+KS4gCgkJCUFuIGltcGxlbWVudGF0aW9uIGlzIGdpdmVuIGJlbG93OjwvcD4KCQk8cHJlPnRlbXBsYXRlJmx0O2NsYXNzIFQmZ3Q7IGNsYXNzIHBvaW50ZXIKewpwcml2YXRlOgoKICAgIFQgKiBwXzsKCnB1YmxpYzoKCiAgICBleHBsaWNpdCBwb2ludGVyKFQgKiBwKTogcF8ocCkKICAgIHsKICAgIH0KCiAgICBzaGFyZWRfcHRyJmx0O1QmZ3Q7IG9wZXJhdG9yLSZndDsoKSBjb25zdAogICAgewogICAgICAgIHBfLSZndDtwcmVmaXgoKTsKICAgICAgICByZXR1cm4gc2hhcmVkX3B0ciZsdDtUJmd0OyhwXywgPEEgaHJlZj0iLi4vYmluZC9tZW1fZm4uaHRtbCIgPm1lbV9mbjwvQT4oJmFtcDtUOjpzdWZmaXgpKTsKICAgIH0KfTsKCmNsYXNzIFgKewpwcml2YXRlOgoKICAgIHZvaWQgcHJlZml4KCk7CiAgICB2b2lkIHN1ZmZpeCgpOwogICAgZnJpZW5kIGNsYXNzIHBvaW50ZXImbHQ7WCZndDs7CiAgICAKcHVibGljOgoKICAgIHZvaWQgZigpOwogICAgdm9pZCBnKCk7Cn07CgppbnQgbWFpbigpCnsKICAgIFggeDsKCiAgICBwb2ludGVyJmx0O1gmZ3Q7IHB4KCZhbXA7eCk7CgogICAgcHgtJmd0O2YoKTsKICAgIHB4LSZndDtnKCk7Cn0KPC9wcmU+CgkJPGgyPjxBIG5hbWU9ImRlbGF5ZWQiPkRlbGF5ZWQgZGVhbGxvY2F0aW9uPC9BPjwvaDI+CgkJPHA+SW4gc29tZSBzaXR1YXRpb25zLCBhIHNpbmdsZSA8Y29kZT5weC5yZXNldCgpPC9jb2RlPiBjYW4gdHJpZ2dlciBhbiBleHBlbnNpdmUgCgkJCWRlYWxsb2NhdGlvbiBpbiBhIHBlcmZvcm1hbmNlLWNyaXRpY2FsIHJlZ2lvbjo8L3A+CgkJPHByZT5jbGFzcyBYOyAvLyB+WCBpcyBleHBlbnNpdmUKCmNsYXNzIFkKewogICAgc2hhcmVkX3B0ciZsdDtYJmd0OyBweDsKCnB1YmxpYzoKCiAgICB2b2lkIGYoKQogICAgewogICAgICAgIHB4LnJlc2V0KCk7CiAgICB9Cn07CjwvcHJlPgoJCTxwPlRoZSBzb2x1dGlvbiBpcyB0byBwb3N0cG9uZSB0aGUgcG90ZW50aWFsIGRlYWxsb2NhdGlvbiBieSBtb3ZpbmcgPGNvZGU+cHg8L2NvZGU+IAoJCQl0byBhIGRlZGljYXRlZCBmcmVlIGxpc3QgdGhhdCBjYW4gYmUgcGVyaW9kaWNhbGx5IGVtcHRpZWQgd2hlbiBwZXJmb3JtYW5jZSBhbmQgCgkJCXJlc3BvbnNlIHRpbWVzIGFyZSBub3QgYW4gaXNzdWU6PC9wPgoJCTxwcmU+dmVjdG9yJmx0OyBzaGFyZWRfcHRyJmx0O3ZvaWQmZ3Q7ICZndDsgZnJlZV9saXN0OwoKY2xhc3MgWQp7CiAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHB4OwoKcHVibGljOgoKICAgIHZvaWQgZigpCiAgICB7CiAgICAgICAgZnJlZV9saXN0LnB1c2hfYmFjayhweCk7CiAgICAgICAgcHgucmVzZXQoKTsKICAgIH0KfTsKCi8vIHBlcmlvZGljYWxseSBpbnZva2UgZnJlZV9saXN0LmNsZWFyKCkgd2hlbiBjb252ZW5pZW50CjwvcHJlPgoJCTxwPkFub3RoZXIgdmFyaWF0aW9uIGlzIHRvIG1vdmUgdGhlIGZyZWUgbGlzdCBsb2dpYyB0byB0aGUgY29uc3RydWN0aW9uIHBvaW50IGJ5IAoJCQl1c2luZyBhIGRlbGF5ZWQgZGVsZXRlcjo8L3A+CgkJPHByZT5zdHJ1Y3QgZGVsYXllZF9kZWxldGVyCnsKICAgIHRlbXBsYXRlJmx0O2NsYXNzIFQmZ3Q7IHZvaWQgb3BlcmF0b3IoKShUICogcCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHNoYXJlZF9wdHImbHQ7dm9pZCZndDsgcHYocCk7CiAgICAgICAgICAgIGZyZWVfbGlzdC5wdXNoX2JhY2socHYpOwogICAgICAgIH0KICAgICAgICBjYXRjaCguLi4pCiAgICAgICAgewogICAgICAgIH0KICAgIH0KfTsKPC9wcmU+CgkJPGgyPjxBIG5hbWU9IndlYWtfd2l0aG91dF9zaGFyZWQiPldlYWsgcG9pbnRlcnMgdG8gb2JqZWN0cyBub3QgbWFuYWdlZCBieSBhIDxjb2RlPnNoYXJlZF9wdHI8L2NvZGU+PC9BPjwvaDI+CgkJPHA+TWFrZSB0aGUgb2JqZWN0IGhvbGQgYSA8Y29kZT5zaGFyZWRfcHRyPC9jb2RlPiB0byBpdHNlbGYsIHVzaW5nIGEgPGNvZGU+bnVsbF9kZWxldGVyPC9jb2RlPjo8L3A+CgkJPHByZT5jbGFzcyBYCnsKcHJpdmF0ZToKCiAgICBzaGFyZWRfcHRyJmx0O1gmZ3Q7IHRoaXNfOwogICAgaW50IGlfOwoKcHVibGljOgoKICAgIGV4cGxpY2l0IFgoaW50IGkpOiB0aGlzXyh0aGlzLCBudWxsX2RlbGV0ZXIoKSksIGlfKGkpCiAgICB7CiAgICB9CgogICAgLy8gcmVwZWF0IGluIGFsbCBjb25zdHJ1Y3RvcnMgKGluY2x1ZGluZyB0aGUgY29weSBjb25zdHJ1Y3RvciEpCgogICAgWChYIGNvbnN0ICZhbXA7IHJocyk6IHRoaXNfKHRoaXMsIG51bGxfZGVsZXRlcigpKSwgaV8ocmhzLmlfKQogICAgewogICAgfQoKICAgIC8vIGRvIG5vdCBmb3JnZXQgdG8gbm90IGFzc2lnbiB0aGlzXyBpbiB0aGUgY29weSBhc3NpZ25tZW50CgogICAgWCAmYW1wOyBvcGVyYXRvcj0oWCBjb25zdCAmYW1wOyByaHMpCiAgICB7CgkgICAgaV8gPSByaHMuaV87CiAgICB9CgogICAgd2Vha19wdHImbHQ7WCZndDsgZ2V0X3dlYWtfcHRyKCkgY29uc3QgeyByZXR1cm4gdGhpc187IH0KfTsKPC9wcmU+CgkJPHA+V2hlbiB0aGUgb2JqZWN0J3MgbGlmZXRpbWUgZW5kcywgPGNvZGU+WDo6dGhpc188L2NvZGU+IHdpbGwgYmUgZGVzdHJveWVkLCBhbmQgCgkJCWFsbCB3ZWFrIHBvaW50ZXJzIHdpbGwgYXV0b21hdGljYWxseSBleHBpcmUuPC9wPgoJCTxocj4KCQk8cD4kRGF0ZTogMjAwNi0xMS0wOSAxNToyNDoyMyAtMDUwMCAoVGh1LCAwOSBOb3YgMjAwNikgJDwvcD4KCQk8cD48c21hbGw+Q29weXJpZ2h0IKkgMjAwMyBQZXRlciBEaW1vdi4gRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJvb3N0IFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gCgkJCQkxLjAuIFNlZSBhY2NvbXBhbnlpbmcgZmlsZSA8QSBocmVmPSIuLi8uLi9MSUNFTlNFXzFfMC50eHQiPkxJQ0VOU0VfMV8wLnR4dDwvQT4gb3IgCgkJCQljb3B5IGF0IDxBIGhyZWY9Imh0dHA6Ly93d3cuYm9vc3Qub3JnL0xJQ0VOU0VfMV8wLnR4dCI+aHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0PC9BPi48L3NtYWxsPjwvcD4KCTwvYm9keT4KPC9odG1sPgo=