"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8112],{84106:function(g,I,C){var A=C(96636);I.lB=void 0,(F=I.lB||(I.lB={})).MARKET_CANDLE="mktc",F.MARK_CANDLE="mrkc",I.DI=void 0,(w=I.DI||(I.DI={})).IndexQuote20_H="index_quote_20.H.",w.IndexQuote200_H="index_quote_200.H.",w.InstrumentInfo_H="instrument_info.H.",w.InstrumentInfo_M="instrument_info.M.",w.InstrumentInfoAll="instrument_info_v3.all",w.PublicNotice="public.notice",w.OrderBook="orderBook_",w.RecentTrade="recently_trade.H.",w.TimeCoinSymbolNotify="public.symbol.notify",w.MT5TickersAll="mt5.tickers.all",w.MT5Kline="mt5.kline.",w.MT5OrderBook="mt5.ob_",w.AlphaTickersAll="alpha.ticker.all",I.iX=void 0,(J=I.iX||(I.iX={})).BUY="Buy",J.SELL="Sell",I.jH=void 0,(n=I.jH||(I.jH={})).CONNECT="connect",n.CONNECTED="connected",n.RECONNECT="reconnect",n.CLOSE="close",n.WSOT="WSOT",n.WSFCT="WSFCT",n.CLOSE_BY_OTHER="close_by_other",n.OPEN_ERROR="open_error",n.HEART_ERROR="heart_error",n.HEART_BACK="heart_back",n.ERROR="error",n.RECONNECT_FAILED="reconnect_failed",n.RECONNECT_START="reconnect_start",I.$H=void 0,(D=I.$H||(I.$H={})).OrderBook="spread.orderBook_",D.InstrumentInfo="spread.instrument_info.",D.InstrumentInfoAll="spread.instrument_info.all",D.RecentTrade="spread.recent_trades.",I.o_=void 0,(I.o_||(I.o_={})).OrderBook="ob_";var Z="/realtime_w";function G(g,I){for(var C=0;C0},enumerable:!1,configurable:!0}),I.prototype._trySubscribe=function(I){return this._throwIfClosed(),g.prototype._trySubscribe.call(this,I)},I.prototype._subscribe=function(g){return this._throwIfClosed(),this._checkFinalizedStatuses(g),this._innerSubscribe(g)},I.prototype._innerSubscribe=function(g){var I=this,C=this.hasError,A=this.isStopped,Z=this.observers;return C||A?W:(this.currentObservers=null,Z.push(g),new m(function(){I.currentObservers=null,i(Z,g)}))},I.prototype._checkFinalizedStatuses=function(g){var I=this.hasError,C=this.thrownError,A=this.isStopped;I?g.error(C):A&&g.complete()},I.prototype.asObservable=function(){var g=new u;return g.source=this,g},I.create=function(g,I){return new U(g,I)},I}(u),U=function(g){function I(I,C){var A=g.call(this)||this;return A.destination=I,A.source=C,A}return A.__extends(I,g),I.prototype.next=function(g){var I,C;null===(C=null===(I=this.destination)||void 0===I?void 0:I.next)||void 0===C||C.call(I,g)},I.prototype.error=function(g){var I,C;null===(C=null===(I=this.destination)||void 0===I?void 0:I.error)||void 0===C||C.call(I,g)},I.prototype.complete=function(){var g,I;null===(I=null===(g=this.destination)||void 0===g?void 0:g.complete)||void 0===I||I.call(g)},I.prototype._subscribe=function(g){var I,C;return null!==(C=null===(I=this.source)||void 0===I?void 0:I.subscribe(g))&&void 0!==C?C:W},I}(T),M=function(g){function I(I){var C=g.call(this)||this;return C._value=I,C}return A.__extends(I,g),Object.defineProperty(I.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),I.prototype._subscribe=function(I){var C=g.prototype._subscribe.call(this,I);return C.closed||I.next(this._value),C},I.prototype.getValue=function(){var g=this.hasError,I=this.thrownError,C=this._value;if(g)throw I;return this._throwIfClosed(),C},I.prototype.next=function(I){g.prototype.next.call(this,this._value=I)},I}(T),t=(v="Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkociwgYSkgewogICAgKG51bGwgPT0gYSB8fCBhID4gci5sZW5ndGgpICYmIChhID0gci5sZW5ndGgpOwogICAgZm9yICh2YXIgZSA9IDAsIG4gPSBBcnJheShhKTsgZSA8IGE7IGUrKykgbltlXSA9IHJbZV07CiAgICByZXR1cm4gbjsKICB9CiAgZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKHIpIHsKICAgIGlmIChBcnJheS5pc0FycmF5KHIpKSByZXR1cm4gcjsKICB9CiAgZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKHIpIHsKICAgIGlmIChBcnJheS5pc0FycmF5KHIpKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkocik7CiAgfQogIGZ1bmN0aW9uIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoZSkgewogICAgaWYgKHZvaWQgMCA9PT0gZSkgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWQiKTsKICAgIHJldHVybiBlOwogIH0KICBmdW5jdGlvbiBfY2FsbFN1cGVyKHQsIG8sIGUpIHsKICAgIHJldHVybiBvID0gX2dldFByb3RvdHlwZU9mKG8pLCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0LCBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgPyBSZWZsZWN0LmNvbnN0cnVjdChvLCBlIHx8IFtdLCBfZ2V0UHJvdG90eXBlT2YodCkuY29uc3RydWN0b3IpIDogby5hcHBseSh0LCBlKSk7CiAgfQogIGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayQxKGEsIG4pIHsKICAgIGlmICghKGEgaW5zdGFuY2VvZiBuKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIik7CiAgfQogIGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDEoZSwgcikgewogICAgZm9yICh2YXIgdCA9IDA7IHQgPCByLmxlbmd0aDsgdCsrKSB7CiAgICAgIHZhciBvID0gclt0XTsKICAgICAgby5lbnVtZXJhYmxlID0gby5lbnVtZXJhYmxlIHx8ICExLCBvLmNvbmZpZ3VyYWJsZSA9ICEwLCAidmFsdWUiIGluIG8gJiYgKG8ud3JpdGFibGUgPSAhMCksIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLCBfdG9Qcm9wZXJ0eUtleShvLmtleSksIG8pOwogICAgfQogIH0KICBmdW5jdGlvbiBfY3JlYXRlQ2xhc3MkMShlLCByLCB0KSB7CiAgICByZXR1cm4gciAmJiBfZGVmaW5lUHJvcGVydGllcyQxKGUucHJvdG90eXBlLCByKSwgdCAmJiBfZGVmaW5lUHJvcGVydGllcyQxKGUsIHQpLCBPYmplY3QuZGVmaW5lUHJvcGVydHkoZSwgInByb3RvdHlwZSIsIHsKICAgICAgd3JpdGFibGU6ICExCiAgICB9KSwgZTsKICB9CiAgZnVuY3Rpb24gX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIociwgZSkgewogICAgdmFyIHQgPSAidW5kZWZpbmVkIiAhPSB0eXBlb2YgU3ltYm9sICYmIHJbU3ltYm9sLml0ZXJhdG9yXSB8fCByWyJAQGl0ZXJhdG9yIl07CiAgICBpZiAoIXQpIHsKICAgICAgaWYgKEFycmF5LmlzQXJyYXkocikgfHwgKHQgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkocikpIHx8IGUgJiYgciAmJiAibnVtYmVyIiA9PSB0eXBlb2Ygci5sZW5ndGgpIHsKICAgICAgICB0ICYmIChyID0gdCk7CiAgICAgICAgdmFyIG4gPSAwLAogICAgICAgICAgRiA9IGZ1bmN0aW9uICgpIHt9OwogICAgICAgIHJldHVybiB7CiAgICAgICAgICBzOiBGLAogICAgICAgICAgbjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gbiA+PSByLmxlbmd0aCA/IHsKICAgICAgICAgICAgICBkb25lOiAhMAogICAgICAgICAgICB9IDogewogICAgICAgICAgICAgIGRvbmU6ICExLAogICAgICAgICAgICAgIHZhbHVlOiByW24rK10KICAgICAgICAgICAgfTsKICAgICAgICAgIH0sCiAgICAgICAgICBlOiBmdW5jdGlvbiAocikgewogICAgICAgICAgICB0aHJvdyByOwogICAgICAgICAgfSwKICAgICAgICAgIGY6IEYKICAgICAgICB9OwogICAgICB9CiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIkludmFsaWQgYXR0ZW1wdCB0byBpdGVyYXRlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC4iKTsKICAgIH0KICAgIHZhciBvLAogICAgICBhID0gITAsCiAgICAgIHUgPSAhMTsKICAgIHJldHVybiB7CiAgICAgIHM6IGZ1bmN0aW9uICgpIHsKICAgICAgICB0ID0gdC5jYWxsKHIpOwogICAgICB9LAogICAgICBuOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHIgPSB0Lm5leHQoKTsKICAgICAgICByZXR1cm4gYSA9IHIuZG9uZSwgcjsKICAgICAgfSwKICAgICAgZTogZnVuY3Rpb24gKHIpIHsKICAgICAgICB1ID0gITAsIG8gPSByOwogICAgICB9LAogICAgICBmOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGEgfHwgbnVsbCA9PSB0LnJldHVybiB8fCB0LnJldHVybigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBpZiAodSkgdGhyb3cgbzsKICAgICAgICB9CiAgICAgIH0KICAgIH07CiAgfQogIGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eSQxKGUsIHIsIHQpIHsKICAgIHJldHVybiAociA9IF90b1Byb3BlcnR5S2V5KHIpKSBpbiBlID8gT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsIHIsIHsKICAgICAgdmFsdWU6IHQsCiAgICAgIGVudW1lcmFibGU6ICEwLAogICAgICBjb25maWd1cmFibGU6ICEwLAogICAgICB3cml0YWJsZTogITAKICAgIH0pIDogZVtyXSA9IHQsIGU7CiAgfQogIGZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZih0KSB7CiAgICByZXR1cm4gX2dldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LmdldFByb3RvdHlwZU9mLmJpbmQoKSA6IGZ1bmN0aW9uICh0KSB7CiAgICAgIHJldHVybiB0Ll9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YodCk7CiAgICB9LCBfZ2V0UHJvdG90eXBlT2YodCk7CiAgfQogIGZ1bmN0aW9uIF9pbmhlcml0cyh0LCBlKSB7CiAgICBpZiAoImZ1bmN0aW9uIiAhPSB0eXBlb2YgZSAmJiBudWxsICE9PSBlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiIpOwogICAgdC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKGUgJiYgZS5wcm90b3R5cGUsIHsKICAgICAgY29uc3RydWN0b3I6IHsKICAgICAgICB2YWx1ZTogdCwKICAgICAgICB3cml0YWJsZTogITAsCiAgICAgICAgY29uZmlndXJhYmxlOiAhMAogICAgICB9CiAgICB9KSwgT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsICJwcm90b3R5cGUiLCB7CiAgICAgIHdyaXRhYmxlOiAhMQogICAgfSksIGUgJiYgX3NldFByb3RvdHlwZU9mKHQsIGUpOwogIH0KICBmdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgewogICAgdHJ5IHsKICAgICAgdmFyIHQgPSAhQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOwogICAgfSBjYXRjaCAodCkge30KICAgIHJldHVybiAoX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IGZ1bmN0aW9uICgpIHsKICAgICAgcmV0dXJuICEhdDsKICAgIH0pKCk7CiAgfQogIGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkocikgewogICAgaWYgKCJ1bmRlZmluZWQiICE9IHR5cGVvZiBTeW1ib2wgJiYgbnVsbCAhPSByW1N5bWJvbC5pdGVyYXRvcl0gfHwgbnVsbCAhPSByWyJAQGl0ZXJhdG9yIl0pIHJldHVybiBBcnJheS5mcm9tKHIpOwogIH0KICBmdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5TGltaXQociwgbCkgewogICAgdmFyIHQgPSBudWxsID09IHIgPyBudWxsIDogInVuZGVmaW5lZCIgIT0gdHlwZW9mIFN5bWJvbCAmJiByW1N5bWJvbC5pdGVyYXRvcl0gfHwgclsiQEBpdGVyYXRvciJdOwogICAgaWYgKG51bGwgIT0gdCkgewogICAgICB2YXIgZSwKICAgICAgICBuLAogICAgICAgIGksCiAgICAgICAgdSwKICAgICAgICBhID0gW10sCiAgICAgICAgZiA9ICEwLAogICAgICAgIG8gPSAhMTsKICAgICAgdHJ5IHsKICAgICAgICBpZiAoaSA9ICh0ID0gdC5jYWxsKHIpKS5uZXh0LCAwID09PSBsKSB7CiAgICAgICAgICBpZiAoT2JqZWN0KHQpICE9PSB0KSByZXR1cm47CiAgICAgICAgICBmID0gITE7CiAgICAgICAgfSBlbHNlIGZvciAoOyAhKGYgPSAoZSA9IGkuY2FsbCh0KSkuZG9uZSkgJiYgKGEucHVzaChlLnZhbHVlKSwgYS5sZW5ndGggIT09IGwpOyBmID0gITApOwogICAgICB9IGNhdGNoIChyKSB7CiAgICAgICAgbyA9ICEwLCBuID0gcjsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKCFmICYmIG51bGwgIT0gdC5yZXR1cm4gJiYgKHUgPSB0LnJldHVybigpLCBPYmplY3QodSkgIT09IHUpKSByZXR1cm47CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIGlmIChvKSB0aHJvdyBuOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gYTsKICAgIH0KICB9CiAgZnVuY3Rpb24gX25vbkl0ZXJhYmxlUmVzdCgpIHsKICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2UuXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuIik7CiAgfQogIGZ1bmN0aW9uIF9ub25JdGVyYWJsZVNwcmVhZCgpIHsKICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIkludmFsaWQgYXR0ZW1wdCB0byBzcHJlYWQgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxuSW4gb3JkZXIgdG8gYmUgaXRlcmFibGUsIG5vbi1hcnJheSBvYmplY3RzIG11c3QgaGF2ZSBhIFtTeW1ib2wuaXRlcmF0b3JdKCkgbWV0aG9kLiIpOwogIH0KICBmdW5jdGlvbiBvd25LZXlzJDEoZSwgcikgewogICAgdmFyIHQgPSBPYmplY3Qua2V5cyhlKTsKICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7CiAgICAgIHZhciBvID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhlKTsKICAgICAgciAmJiAobyA9IG8uZmlsdGVyKGZ1bmN0aW9uIChyKSB7CiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZSwgcikuZW51bWVyYWJsZTsKICAgICAgfSkpLCB0LnB1c2guYXBwbHkodCwgbyk7CiAgICB9CiAgICByZXR1cm4gdDsKICB9CiAgZnVuY3Rpb24gX29iamVjdFNwcmVhZDIkMihlKSB7CiAgICBmb3IgKHZhciByID0gMTsgciA8IGFyZ3VtZW50cy5sZW5ndGg7IHIrKykgewogICAgICB2YXIgdCA9IG51bGwgIT0gYXJndW1lbnRzW3JdID8gYXJndW1lbnRzW3JdIDoge307CiAgICAgIHIgJSAyID8gb3duS2V5cyQxKE9iamVjdCh0KSwgITApLmZvckVhY2goZnVuY3Rpb24gKHIpIHsKICAgICAgICBfZGVmaW5lUHJvcGVydHkkMShlLCByLCB0W3JdKTsKICAgICAgfSkgOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGUsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHQpKSA6IG93bktleXMkMShPYmplY3QodCkpLmZvckVhY2goZnVuY3Rpb24gKHIpIHsKICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZSwgciwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0LCByKSk7CiAgICAgIH0pOwogICAgfQogICAgcmV0dXJuIGU7CiAgfQogIGZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHQsIGUpIHsKICAgIGlmIChlICYmICgib2JqZWN0IiA9PSB0eXBlb2YgZSB8fCAiZnVuY3Rpb24iID09IHR5cGVvZiBlKSkgcmV0dXJuIGU7CiAgICBpZiAodm9pZCAwICE9PSBlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCJEZXJpdmVkIGNvbnN0cnVjdG9ycyBtYXkgb25seSByZXR1cm4gb2JqZWN0IG9yIHVuZGVmaW5lZCIpOwogICAgcmV0dXJuIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQodCk7CiAgfQogIGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZih0LCBlKSB7CiAgICByZXR1cm4gX3NldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mLmJpbmQoKSA6IGZ1bmN0aW9uICh0LCBlKSB7CiAgICAgIHJldHVybiB0Ll9fcHJvdG9fXyA9IGUsIHQ7CiAgICB9LCBfc2V0UHJvdG90eXBlT2YodCwgZSk7CiAgfQogIGZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KHIsIGUpIHsKICAgIHJldHVybiBfYXJyYXlXaXRoSG9sZXMocikgfHwgX2l0ZXJhYmxlVG9BcnJheUxpbWl0KHIsIGUpIHx8IF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShyLCBlKSB8fCBfbm9uSXRlcmFibGVSZXN0KCk7CiAgfQogIGZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShyKSB7CiAgICByZXR1cm4gX2FycmF5V2l0aG91dEhvbGVzKHIpIHx8IF9pdGVyYWJsZVRvQXJyYXkocikgfHwgX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KHIpIHx8IF9ub25JdGVyYWJsZVNwcmVhZCgpOwogIH0KICBmdW5jdGlvbiBfdG9QcmltaXRpdmUodCwgcikgewogICAgaWYgKCJvYmplY3QiICE9IHR5cGVvZiB0IHx8ICF0KSByZXR1cm4gdDsKICAgIHZhciBlID0gdFtTeW1ib2wudG9QcmltaXRpdmVdOwogICAgaWYgKHZvaWQgMCAhPT0gZSkgewogICAgICB2YXIgaSA9IGUuY2FsbCh0LCByIHx8ICJkZWZhdWx0Iik7CiAgICAgIGlmICgib2JqZWN0IiAhPSB0eXBlb2YgaSkgcmV0dXJuIGk7CiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuIik7CiAgICB9CiAgICByZXR1cm4gKCJzdHJpbmciID09PSByID8gU3RyaW5nIDogTnVtYmVyKSh0KTsKICB9CiAgZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkodCkgewogICAgdmFyIGkgPSBfdG9QcmltaXRpdmUodCwgInN0cmluZyIpOwogICAgcmV0dXJuICJzeW1ib2wiID09IHR5cGVvZiBpID8gaSA6IGkgKyAiIjsKICB9CiAgZnVuY3Rpb24gX3R5cGVvZiQxKG8pIHsKICAgICJAYmFiZWwvaGVscGVycyAtIHR5cGVvZiI7CgogICAgcmV0dXJuIF90eXBlb2YkMSA9ICJmdW5jdGlvbiIgPT0gdHlwZW9mIFN5bWJvbCAmJiAic3ltYm9sIiA9PSB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID8gZnVuY3Rpb24gKG8pIHsKICAgICAgcmV0dXJuIHR5cGVvZiBvOwogICAgfSA6IGZ1bmN0aW9uIChvKSB7CiAgICAgIHJldHVybiBvICYmICJmdW5jdGlvbiIgPT0gdHlwZW9mIFN5bWJvbCAmJiBvLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgbyAhPT0gU3ltYm9sLnByb3RvdHlwZSA/ICJzeW1ib2wiIDogdHlwZW9mIG87CiAgICB9LCBfdHlwZW9mJDEobyk7CiAgfQogIGZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShyLCBhKSB7CiAgICBpZiAocikgewogICAgICBpZiAoInN0cmluZyIgPT0gdHlwZW9mIHIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShyLCBhKTsKICAgICAgdmFyIHQgPSB7fS50b1N0cmluZy5jYWxsKHIpLnNsaWNlKDgsIC0xKTsKICAgICAgcmV0dXJuICJPYmplY3QiID09PSB0ICYmIHIuY29uc3RydWN0b3IgJiYgKHQgPSByLmNvbnN0cnVjdG9yLm5hbWUpLCAiTWFwIiA9PT0gdCB8fCAiU2V0IiA9PT0gdCA/IEFycmF5LmZyb20ocikgOiAiQXJndW1lbnRzIiA9PT0gdCB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdCh0KSA/IF9hcnJheUxpa2VUb0FycmF5KHIsIGEpIDogdm9pZCAwOwogICAgfQogIH0KCiAgdmFyIGNvbW1vbmpzR2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDoge307CgogIC8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciAiRnVuY3Rpb25zIiBtZXRob2RzLiAqLwogIHZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7CgogIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwogIHZhciBOQU4kMSA9IDAgLyAwOwoKICAvKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCiAgdmFyIHN5bWJvbFRhZyQxID0gJ1tvYmplY3QgU3ltYm9sXSc7CgogIC8qKiBVc2VkIHRvIG1hdGNoIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UuICovCiAgdmFyIHJlVHJpbSQxID0gL15ccyt8XHMrJC9nOwoKICAvKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqLwogIHZhciByZUlzQmFkSGV4JDEgPSAvXlstK10weFswLTlhLWZdKyQvaTsKCiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqLwogIHZhciByZUlzQmluYXJ5JDEgPSAvXjBiWzAxXSskL2k7CgogIC8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqLwogIHZhciByZUlzT2N0YWwkMSA9IC9eMG9bMC03XSskL2k7CgogIC8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovCiAgdmFyIGZyZWVQYXJzZUludCA9IHBhcnNlSW50OwoKICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqLwogIHZhciBmcmVlR2xvYmFsID0gX3R5cGVvZiQxKGNvbW1vbmpzR2xvYmFsKSA9PSAnb2JqZWN0JyAmJiBjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBjb21tb25qc0dsb2JhbDsKCiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi8KICB2YXIgZnJlZVNlbGYgPSAodHlwZW9mIHNlbGYgPT09ICJ1bmRlZmluZWQiID8gInVuZGVmaW5lZCIgOiBfdHlwZW9mJDEoc2VsZikpID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmOwoKICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi8KICB2YXIgcm9vdCA9IGZyZWVHbG9iYWwgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTsKCiAgLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwogIHZhciBvYmplY3RQcm90byQyID0gT2JqZWN0LnByb3RvdHlwZTsKCiAgLyoqCiAgICogVXNlZCB0byByZXNvbHZlIHRoZQogICAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKQogICAqIG9mIHZhbHVlcy4KICAgKi8KICB2YXIgb2JqZWN0VG9TdHJpbmckMiA9IG9iamVjdFByb3RvJDIudG9TdHJpbmc7CgogIC8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi8KICB2YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXgsCiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjsKCiAgLyoqCiAgICogR2V0cyB0aGUgdGltZXN0YW1wIG9mIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlCiAgICogdGhlIFVuaXggZXBvY2ggKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuCiAgICoKICAgKiBAc3RhdGljCiAgICogQG1lbWJlck9mIF8KICAgKiBAc2luY2UgMi40LjAKICAgKiBAY2F0ZWdvcnkgRGF0ZQogICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVzdGFtcC4KICAgKiBAZXhhbXBsZQogICAqCiAgICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkgewogICAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTsKICAgKiB9LCBfLm5vdygpKTsKICAgKiAvLyA9PiBMb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBpbnZvY2F0aW9uLgogICAqLwogIHZhciBub3cgPSBmdW5jdGlvbiBub3coKSB7CiAgICByZXR1cm4gcm9vdC5EYXRlLm5vdygpOwogIH07CgogIC8qKgogICAqIENyZWF0ZXMgYSBkZWJvdW5jZWQgZnVuY3Rpb24gdGhhdCBkZWxheXMgaW52b2tpbmcgYGZ1bmNgIHVudGlsIGFmdGVyIGB3YWl0YAogICAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhcwogICAqIGludm9rZWQuIFRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gY29tZXMgd2l0aCBhIGBjYW5jZWxgIG1ldGhvZCB0byBjYW5jZWwKICAgKiBkZWxheWVkIGBmdW5jYCBpbnZvY2F0aW9ucyBhbmQgYSBgZmx1c2hgIG1ldGhvZCB0byBpbW1lZGlhdGVseSBpbnZva2UgdGhlbS4KICAgKiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYCBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGUKICAgKiBsZWFkaW5nIGFuZC9vciB0cmFpbGluZyBlZGdlIG9mIHRoZSBgd2FpdGAgdGltZW91dC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkCiAgICogd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbi4gU3Vic2VxdWVudAogICAqIGNhbGxzIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgCiAgICogaW52b2NhdGlvbi4KICAgKgogICAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXMKICAgKiBpbnZva2VkIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIGRlYm91bmNlZCBmdW5jdGlvbgogICAqIGlzIGludm9rZWQgbW9yZSB0aGFuIG9uY2UgZHVyaW5nIHRoZSBgd2FpdGAgdGltZW91dC4KICAgKgogICAqIElmIGB3YWl0YCBpcyBgMGAgYW5kIGBsZWFkaW5nYCBpcyBgZmFsc2VgLCBgZnVuY2AgaW52b2NhdGlvbiBpcyBkZWZlcnJlZAogICAqIHVudGlsIHRvIHRoZSBuZXh0IHRpY2ssIHNpbWlsYXIgdG8gYHNldFRpbWVvdXRgIHdpdGggYSB0aW1lb3V0IG9mIGAwYC4KICAgKgogICAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKQogICAqIGZvciBkZXRhaWxzIG92ZXIgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYF8uZGVib3VuY2VgIGFuZCBgXy50aHJvdHRsZWAuCiAgICoKICAgKiBAc3RhdGljCiAgICogQG1lbWJlck9mIF8KICAgKiBAc2luY2UgMC4xLjAKICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb24KICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWJvdW5jZS4KICAgKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkuCiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuCiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sZWFkaW5nPWZhbHNlXQogICAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuCiAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFdhaXRdCiAgICogIFRoZSBtYXhpbXVtIHRpbWUgYGZ1bmNgIGlzIGFsbG93ZWQgdG8gYmUgZGVsYXllZCBiZWZvcmUgaXQncyBpbnZva2VkLgogICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV0KICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC4KICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBkZWJvdW5jZWQgZnVuY3Rpb24uCiAgICogQGV4YW1wbGUKICAgKgogICAqIC8vIEF2b2lkIGNvc3RseSBjYWxjdWxhdGlvbnMgd2hpbGUgdGhlIHdpbmRvdyBzaXplIGlzIGluIGZsdXguCiAgICogalF1ZXJ5KHdpbmRvdykub24oJ3Jlc2l6ZScsIF8uZGVib3VuY2UoY2FsY3VsYXRlTGF5b3V0LCAxNTApKTsKICAgKgogICAqIC8vIEludm9rZSBgc2VuZE1haWxgIHdoZW4gY2xpY2tlZCwgZGVib3VuY2luZyBzdWJzZXF1ZW50IGNhbGxzLgogICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCBfLmRlYm91bmNlKHNlbmRNYWlsLCAzMDAsIHsKICAgKiAgICdsZWFkaW5nJzogdHJ1ZSwKICAgKiAgICd0cmFpbGluZyc6IGZhbHNlCiAgICogfSkpOwogICAqCiAgICogLy8gRW5zdXJlIGBiYXRjaExvZ2AgaXMgaW52b2tlZCBvbmNlIGFmdGVyIDEgc2Vjb25kIG9mIGRlYm91bmNlZCBjYWxscy4KICAgKiB2YXIgZGVib3VuY2VkID0gXy5kZWJvdW5jZShiYXRjaExvZywgMjUwLCB7ICdtYXhXYWl0JzogMTAwMCB9KTsKICAgKiB2YXIgc291cmNlID0gbmV3IEV2ZW50U291cmNlKCcvc3RyZWFtJyk7CiAgICogalF1ZXJ5KHNvdXJjZSkub24oJ21lc3NhZ2UnLCBkZWJvdW5jZWQpOwogICAqCiAgICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyBkZWJvdW5jZWQgaW52b2NhdGlvbi4KICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCBkZWJvdW5jZWQuY2FuY2VsKTsKICAgKi8KICBmdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7CiAgICB2YXIgbGFzdEFyZ3MsCiAgICAgIGxhc3RUaGlzLAogICAgICBtYXhXYWl0LAogICAgICByZXN1bHQsCiAgICAgIHRpbWVySWQsCiAgICAgIGxhc3RDYWxsVGltZSwKICAgICAgbGFzdEludm9rZVRpbWUgPSAwLAogICAgICBsZWFkaW5nID0gZmFsc2UsCiAgICAgIG1heGluZyA9IGZhbHNlLAogICAgICB0cmFpbGluZyA9IHRydWU7CiAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykgewogICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7CiAgICB9CiAgICB3YWl0ID0gdG9OdW1iZXIkMih3YWl0KSB8fCAwOwogICAgaWYgKGlzT2JqZWN0JDIob3B0aW9ucykpIHsKICAgICAgbGVhZGluZyA9ICEhb3B0aW9ucy5sZWFkaW5nOwogICAgICBtYXhpbmcgPSAnbWF4V2FpdCcgaW4gb3B0aW9uczsKICAgICAgbWF4V2FpdCA9IG1heGluZyA/IG5hdGl2ZU1heCh0b051bWJlciQyKG9wdGlvbnMubWF4V2FpdCkgfHwgMCwgd2FpdCkgOiBtYXhXYWl0OwogICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nOwogICAgfQogICAgZnVuY3Rpb24gaW52b2tlRnVuYyh0aW1lKSB7CiAgICAgIHZhciBhcmdzID0gbGFzdEFyZ3MsCiAgICAgICAgdGhpc0FyZyA9IGxhc3RUaGlzOwogICAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkOwogICAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7CiAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICBmdW5jdGlvbiBsZWFkaW5nRWRnZSh0aW1lKSB7CiAgICAgIC8vIFJlc2V0IGFueSBgbWF4V2FpdGAgdGltZXIuCiAgICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTsKICAgICAgLy8gU3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgdHJhaWxpbmcgZWRnZS4KICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTsKICAgICAgLy8gSW52b2tlIHRoZSBsZWFkaW5nIGVkZ2UuCiAgICAgIHJldHVybiBsZWFkaW5nID8gaW52b2tlRnVuYyh0aW1lKSA6IHJlc3VsdDsKICAgIH0KICAgIGZ1bmN0aW9uIHJlbWFpbmluZ1dhaXQodGltZSkgewogICAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLAogICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWUsCiAgICAgICAgcmVzdWx0ID0gd2FpdCAtIHRpbWVTaW5jZUxhc3RDYWxsOwogICAgICByZXR1cm4gbWF4aW5nID8gbmF0aXZlTWluKHJlc3VsdCwgbWF4V2FpdCAtIHRpbWVTaW5jZUxhc3RJbnZva2UpIDogcmVzdWx0OwogICAgfQogICAgZnVuY3Rpb24gc2hvdWxkSW52b2tlKHRpbWUpIHsKICAgICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSwKICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lOwoKICAgICAgLy8gRWl0aGVyIHRoaXMgaXMgdGhlIGZpcnN0IGNhbGwsIGFjdGl2aXR5IGhhcyBzdG9wcGVkIGFuZCB3ZSdyZSBhdCB0aGUKICAgICAgLy8gdHJhaWxpbmcgZWRnZSwgdGhlIHN5c3RlbSB0aW1lIGhhcyBnb25lIGJhY2t3YXJkcyBhbmQgd2UncmUgdHJlYXRpbmcKICAgICAgLy8gaXQgYXMgdGhlIHRyYWlsaW5nIGVkZ2UsIG9yIHdlJ3ZlIGhpdCB0aGUgYG1heFdhaXRgIGxpbWl0LgogICAgICByZXR1cm4gbGFzdENhbGxUaW1lID09PSB1bmRlZmluZWQgfHwgdGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCB8fCB0aW1lU2luY2VMYXN0Q2FsbCA8IDAgfHwgbWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdDsKICAgIH0KICAgIGZ1bmN0aW9uIHRpbWVyRXhwaXJlZCgpIHsKICAgICAgdmFyIHRpbWUgPSBub3coKTsKICAgICAgaWYgKHNob3VsZEludm9rZSh0aW1lKSkgewogICAgICAgIHJldHVybiB0cmFpbGluZ0VkZ2UodGltZSk7CiAgICAgIH0KICAgICAgLy8gUmVzdGFydCB0aGUgdGltZXIuCiAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgcmVtYWluaW5nV2FpdCh0aW1lKSk7CiAgICB9CiAgICBmdW5jdGlvbiB0cmFpbGluZ0VkZ2UodGltZSkgewogICAgICB0aW1lcklkID0gdW5kZWZpbmVkOwoKICAgICAgLy8gT25seSBpbnZva2UgaWYgd2UgaGF2ZSBgbGFzdEFyZ3NgIHdoaWNoIG1lYW5zIGBmdW5jYCBoYXMgYmVlbgogICAgICAvLyBkZWJvdW5jZWQgYXQgbGVhc3Qgb25jZS4KICAgICAgaWYgKHRyYWlsaW5nICYmIGxhc3RBcmdzKSB7CiAgICAgICAgcmV0dXJuIGludm9rZUZ1bmModGltZSk7CiAgICAgIH0KICAgICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIGZ1bmN0aW9uIGNhbmNlbCgpIHsKICAgICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkgewogICAgICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTsKICAgICAgfQogICAgICBsYXN0SW52b2tlVGltZSA9IDA7CiAgICAgIGxhc3RBcmdzID0gbGFzdENhbGxUaW1lID0gbGFzdFRoaXMgPSB0aW1lcklkID0gdW5kZWZpbmVkOwogICAgfQogICAgZnVuY3Rpb24gZmx1c2goKSB7CiAgICAgIHJldHVybiB0aW1lcklkID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiB0cmFpbGluZ0VkZ2Uobm93KCkpOwogICAgfQogICAgZnVuY3Rpb24gZGVib3VuY2VkKCkgewogICAgICB2YXIgdGltZSA9IG5vdygpLAogICAgICAgIGlzSW52b2tpbmcgPSBzaG91bGRJbnZva2UodGltZSk7CiAgICAgIGxhc3RBcmdzID0gYXJndW1lbnRzOwogICAgICBsYXN0VGhpcyA9IHRoaXM7CiAgICAgIGxhc3RDYWxsVGltZSA9IHRpbWU7CiAgICAgIGlmIChpc0ludm9raW5nKSB7CiAgICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgcmV0dXJuIGxlYWRpbmdFZGdlKGxhc3RDYWxsVGltZSk7CiAgICAgICAgfQogICAgICAgIGlmIChtYXhpbmcpIHsKICAgICAgICAgIC8vIEhhbmRsZSBpbnZvY2F0aW9ucyBpbiBhIHRpZ2h0IGxvb3AuCiAgICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpOwogICAgICAgICAgcmV0dXJuIGludm9rZUZ1bmMobGFzdENhbGxUaW1lKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkgewogICAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIGRlYm91bmNlZC5jYW5jZWwgPSBjYW5jZWw7CiAgICBkZWJvdW5jZWQuZmx1c2ggPSBmbHVzaDsKICAgIHJldHVybiBkZWJvdW5jZWQ7CiAgfQoKICAvKioKICAgKiBDcmVhdGVzIGEgdGhyb3R0bGVkIGZ1bmN0aW9uIHRoYXQgb25seSBpbnZva2VzIGBmdW5jYCBhdCBtb3N0IG9uY2UgcGVyCiAgICogZXZlcnkgYHdhaXRgIG1pbGxpc2Vjb25kcy4gVGhlIHRocm90dGxlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAKICAgKiBtZXRob2QgdG8gY2FuY2VsIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvCiAgICogaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgCiAgICogc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YAogICAqIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZCB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUKICAgKiB0aHJvdHRsZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlCiAgICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLgogICAqCiAgICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpcwogICAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uCiAgICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LgogICAqCiAgICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkCiAgICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLgogICAqCiAgICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pCiAgICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC4KICAgKgogICAqIEBzdGF0aWMKICAgKiBAbWVtYmVyT2YgXwogICAqIEBzaW5jZSAwLjEuMAogICAqIEBjYXRlZ29yeSBGdW5jdGlvbgogICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLgogICAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by4KICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC4KICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV0KICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LgogICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV0KICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC4KICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB0aHJvdHRsZWQgZnVuY3Rpb24uCiAgICogQGV4YW1wbGUKICAgKgogICAqIC8vIEF2b2lkIGV4Y2Vzc2l2ZWx5IHVwZGF0aW5nIHRoZSBwb3NpdGlvbiB3aGlsZSBzY3JvbGxpbmcuCiAgICogalF1ZXJ5KHdpbmRvdykub24oJ3Njcm9sbCcsIF8udGhyb3R0bGUodXBkYXRlUG9zaXRpb24sIDEwMCkpOwogICAqCiAgICogLy8gSW52b2tlIGByZW5ld1Rva2VuYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgYnV0IG5vdCBtb3JlIHRoYW4gb25jZSBldmVyeSA1IG1pbnV0ZXMuCiAgICogdmFyIHRocm90dGxlZCA9IF8udGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pOwogICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCB0aHJvdHRsZWQpOwogICAqCiAgICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi4KICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTsKICAgKi8KICBmdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7CiAgICB2YXIgbGVhZGluZyA9IHRydWUsCiAgICAgIHRyYWlsaW5nID0gdHJ1ZTsKICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7CiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTsKICAgIH0KICAgIGlmIChpc09iamVjdCQyKG9wdGlvbnMpKSB7CiAgICAgIGxlYWRpbmcgPSAnbGVhZGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy5sZWFkaW5nIDogbGVhZGluZzsKICAgICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZzsKICAgIH0KICAgIHJldHVybiBkZWJvdW5jZShmdW5jLCB3YWl0LCB7CiAgICAgICdsZWFkaW5nJzogbGVhZGluZywKICAgICAgJ21heFdhaXQnOiB3YWl0LAogICAgICAndHJhaWxpbmcnOiB0cmFpbGluZwogICAgfSk7CiAgfQoKICAvKioKICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUKICAgKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpCiAgICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKQogICAqCiAgICogQHN0YXRpYwogICAqIEBtZW1iZXJPZiBfCiAgICogQHNpbmNlIDAuMS4wCiAgICogQGNhdGVnb3J5IExhbmcKICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC4KICAgKiBAZXhhbXBsZQogICAqCiAgICogXy5pc09iamVjdCh7fSk7CiAgICogLy8gPT4gdHJ1ZQogICAqCiAgICogXy5pc09iamVjdChbMSwgMiwgM10pOwogICAqIC8vID0+IHRydWUKICAgKgogICAqIF8uaXNPYmplY3QoXy5ub29wKTsKICAgKiAvLyA9PiB0cnVlCiAgICoKICAgKiBfLmlzT2JqZWN0KG51bGwpOwogICAqIC8vID0+IGZhbHNlCiAgICovCiAgZnVuY3Rpb24gaXNPYmplY3QkMih2YWx1ZSkgewogICAgdmFyIHR5cGUgPSBfdHlwZW9mJDEodmFsdWUpOwogICAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTsKICB9CgogIC8qKgogICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYAogICAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgIm9iamVjdCIuCiAgICoKICAgKiBAc3RhdGljCiAgICogQG1lbWJlck9mIF8KICAgKiBAc2luY2UgNC4wLjAKICAgKiBAY2F0ZWdvcnkgTGFuZwogICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuCiAgICogQGV4YW1wbGUKICAgKgogICAqIF8uaXNPYmplY3RMaWtlKHt9KTsKICAgKiAvLyA9PiB0cnVlCiAgICoKICAgKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pOwogICAqIC8vID0+IHRydWUKICAgKgogICAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7CiAgICogLy8gPT4gZmFsc2UKICAgKgogICAqIF8uaXNPYmplY3RMaWtlKG51bGwpOwogICAqIC8vID0+IGZhbHNlCiAgICovCiAgZnVuY3Rpb24gaXNPYmplY3RMaWtlJDEodmFsdWUpIHsKICAgIHJldHVybiAhIXZhbHVlICYmIF90eXBlb2YkMSh2YWx1ZSkgPT0gJ29iamVjdCc7CiAgfQoKICAvKioKICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC4KICAgKgogICAqIEBzdGF0aWMKICAgKiBAbWVtYmVyT2YgXwogICAqIEBzaW5jZSA0LjAuMAogICAqIEBjYXRlZ29yeSBMYW5nCiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC4KICAgKiBAZXhhbXBsZQogICAqCiAgICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpOwogICAqIC8vID0+IHRydWUKICAgKgogICAqIF8uaXNTeW1ib2woJ2FiYycpOwogICAqIC8vID0+IGZhbHNlCiAgICovCiAgZnVuY3Rpb24gaXNTeW1ib2wkMSh2YWx1ZSkgewogICAgcmV0dXJuIF90eXBlb2YkMSh2YWx1ZSkgPT0gJ3N5bWJvbCcgfHwgaXNPYmplY3RMaWtlJDEodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nJDIuY2FsbCh2YWx1ZSkgPT0gc3ltYm9sVGFnJDE7CiAgfQoKICAvKioKICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLgogICAqCiAgICogQHN0YXRpYwogICAqIEBtZW1iZXJPZiBfCiAgICogQHNpbmNlIDQuMC4wCiAgICogQGNhdGVnb3J5IExhbmcKICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLgogICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci4KICAgKiBAZXhhbXBsZQogICAqCiAgICogXy50b051bWJlcigzLjIpOwogICAqIC8vID0+IDMuMgogICAqCiAgICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTsKICAgKiAvLyA9PiA1ZS0zMjQKICAgKgogICAqIF8udG9OdW1iZXIoSW5maW5pdHkpOwogICAqIC8vID0+IEluZmluaXR5CiAgICoKICAgKiBfLnRvTnVtYmVyKCczLjInKTsKICAgKiAvLyA9PiAzLjIKICAgKi8KICBmdW5jdGlvbiB0b051bWJlciQyKHZhbHVlKSB7CiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KICAgIGlmIChpc1N5bWJvbCQxKHZhbHVlKSkgewogICAgICByZXR1cm4gTkFOJDE7CiAgICB9CiAgICBpZiAoaXNPYmplY3QkMih2YWx1ZSkpIHsKICAgICAgdmFyIG90aGVyID0gdHlwZW9mIHZhbHVlLnZhbHVlT2YgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnZhbHVlT2YoKSA6IHZhbHVlOwogICAgICB2YWx1ZSA9IGlzT2JqZWN0JDIob3RoZXIpID8gb3RoZXIgKyAnJyA6IG90aGVyOwogICAgfQogICAgaWYgKHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgewogICAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6ICt2YWx1ZTsKICAgIH0KICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZVRyaW0kMSwgJycpOwogICAgdmFyIGlzQmluYXJ5ID0gcmVJc0JpbmFyeSQxLnRlc3QodmFsdWUpOwogICAgcmV0dXJuIGlzQmluYXJ5IHx8IHJlSXNPY3RhbCQxLnRlc3QodmFsdWUpID8gZnJlZVBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCBpc0JpbmFyeSA/IDIgOiA4KSA6IHJlSXNCYWRIZXgkMS50ZXN0KHZhbHVlKSA/IE5BTiQxIDogK3ZhbHVlOwogIH0KICB2YXIgbG9kYXNoX3Rocm90dGxlID0gdGhyb3R0bGU7CgogIHZhciBsaWIgPSB7fTsKCiAgZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdCQxKG9iaikgewogICAgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsKICAgICAgImRlZmF1bHQiOiBvYmoKICAgIH07CiAgfQogIHZhciBpbnRlcm9wUmVxdWlyZURlZmF1bHQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0JDE7CgogIGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHsKICAgIGlmIChrZXkgaW4gb2JqKSB7CiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgewogICAgICAgIHZhbHVlOiB2YWx1ZSwKICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwKICAgICAgICB3cml0YWJsZTogdHJ1ZQogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIG9ialtrZXldID0gdmFsdWU7CiAgICB9CiAgICByZXR1cm4gb2JqOwogIH0KICB2YXIgZGVmaW5lUHJvcGVydHkkMSA9IF9kZWZpbmVQcm9wZXJ0eTsKCiAgdmFyIGRlZmluZVByb3BlcnR5ID0gZGVmaW5lUHJvcGVydHkkMTsKICBmdW5jdGlvbiBvd25LZXlzKG9iamVjdCwgZW51bWVyYWJsZU9ubHkpIHsKICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTsKICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7CiAgICAgIHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpOwogICAgICBpZiAoZW51bWVyYWJsZU9ubHkpIHN5bWJvbHMgPSBzeW1ib2xzLmZpbHRlcihmdW5jdGlvbiAoc3ltKSB7CiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzeW0pLmVudW1lcmFibGU7CiAgICAgIH0pOwogICAgICBrZXlzLnB1c2guYXBwbHkoa2V5cywgc3ltYm9scyk7CiAgICB9CiAgICByZXR1cm4ga2V5czsKICB9CiAgZnVuY3Rpb24gX29iamVjdFNwcmVhZDIkMSh0YXJnZXQpIHsKICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV0gIT0gbnVsbCA/IGFyZ3VtZW50c1tpXSA6IHt9OwogICAgICBpZiAoaSAlIDIpIHsKICAgICAgICBvd25LZXlzKE9iamVjdChzb3VyY2UpLCB0cnVlKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICAgIGRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMpIHsKICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHNvdXJjZSkpOwogICAgICB9IGVsc2UgewogICAgICAgIG93bktleXMoT2JqZWN0KHNvdXJjZSkpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgewogICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwga2V5KSk7CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB0YXJnZXQ7CiAgfQogIHZhciBvYmplY3RTcHJlYWQyID0gX29iamVjdFNwcmVhZDIkMTsKCiAgZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCkgewogICAgaWYgKHNvdXJjZSA9PSBudWxsKSByZXR1cm4ge307CiAgICB2YXIgdGFyZ2V0ID0ge307CiAgICB2YXIgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7CiAgICB2YXIga2V5LCBpOwogICAgZm9yIChpID0gMDsgaSA8IHNvdXJjZUtleXMubGVuZ3RoOyBpKyspIHsKICAgICAga2V5ID0gc291cmNlS2V5c1tpXTsKICAgICAgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTsKICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsKICAgIH0KICAgIHJldHVybiB0YXJnZXQ7CiAgfQogIHZhciBvYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlJDEgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZTsKCiAgdmFyIG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2UgPSBvYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlJDE7CiAgZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKHNvdXJjZSwgZXhjbHVkZWQpIHsKICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgcmV0dXJuIHt9OwogICAgdmFyIHRhcmdldCA9IG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCk7CiAgICB2YXIga2V5LCBpOwogICAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHsKICAgICAgdmFyIHNvdXJjZVN5bWJvbEtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHNvdXJjZSk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBzb3VyY2VTeW1ib2xLZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAga2V5ID0gc291cmNlU3ltYm9sS2V5c1tpXTsKICAgICAgICBpZiAoZXhjbHVkZWQuaW5kZXhPZihrZXkpID49IDApIGNvbnRpbnVlOwogICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHNvdXJjZSwga2V5KSkgY29udGludWU7CiAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHRhcmdldDsKICB9CiAgdmFyIG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzOwoKICBmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7CiAgICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgewogICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24iKTsKICAgIH0KICB9CiAgdmFyIGNsYXNzQ2FsbENoZWNrID0gX2NsYXNzQ2FsbENoZWNrOwoKICBmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07CiAgICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsKICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOwogICAgICBpZiAoInZhbHVlIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsKICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOwogICAgfQogIH0KICBmdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7CiAgICBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsKICAgIGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsKICAgIHJldHVybiBDb25zdHJ1Y3RvcjsKICB9CiAgdmFyIGNyZWF0ZUNsYXNzID0gX2NyZWF0ZUNsYXNzOwoKICBmdW5jdGlvbiBfdHlwZW9mKG9iaikgewogICAgIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mIjsKCiAgICBpZiAodHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSAic3ltYm9sIikgewogICAgICBfdHlwZW9mXzEgPSBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsKICAgICAgICByZXR1cm4gdHlwZW9mIG9iajsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIF90eXBlb2ZfMSA9IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgewogICAgICAgIHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyAic3ltYm9sIiA6IHR5cGVvZiBvYmo7CiAgICAgIH07CiAgICB9CiAgICByZXR1cm4gX3R5cGVvZihvYmopOwogIH0KICB2YXIgX3R5cGVvZl8xID0gX3R5cGVvZjsKCiAgdmFyIGNvbXBvbmVudEVtaXR0ZXIgPSB7ZXhwb3J0czoge319OwoKICAoZnVuY3Rpb24gKG1vZHVsZSkgewogICAgLyoqDQogICAgICogRXhwb3NlIGBFbWl0dGVyYC4NCiAgICAgKi8KCiAgICB7CiAgICAgIG1vZHVsZS5leHBvcnRzID0gRW1pdHRlcjsKICAgIH0KCiAgICAvKioNCiAgICAgKiBJbml0aWFsaXplIGEgbmV3IGBFbWl0dGVyYC4NCiAgICAgKg0KICAgICAqIEBhcGkgcHVibGljDQogICAgICovCgogICAgZnVuY3Rpb24gRW1pdHRlcihvYmopIHsKICAgICAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7CiAgICB9CgogICAgLyoqDQogICAgICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy4NCiAgICAgKg0KICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmoNCiAgICAgKiBAcmV0dXJuIHtPYmplY3R9DQogICAgICogQGFwaSBwcml2YXRlDQogICAgICovCgogICAgZnVuY3Rpb24gbWl4aW4ob2JqKSB7CiAgICAgIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkgewogICAgICAgIG9ialtrZXldID0gRW1pdHRlci5wcm90b3R5cGVba2V5XTsKICAgICAgfQogICAgICByZXR1cm4gb2JqOwogICAgfQoKICAgIC8qKg0KICAgICAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuDQogICAgICoNCiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQNCiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbg0KICAgICAqIEByZXR1cm4ge0VtaXR0ZXJ9DQogICAgICogQGFwaSBwdWJsaWMNCiAgICAgKi8KCiAgICBFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEVtaXR0ZXIucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7CiAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTsKICAgICAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKS5wdXNoKGZuKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9OwoKICAgIC8qKg0KICAgICAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZQ0KICAgICAqIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuDQogICAgICoNCiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQNCiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbg0KICAgICAqIEByZXR1cm4ge0VtaXR0ZXJ9DQogICAgICogQGFwaSBwdWJsaWMNCiAgICAgKi8KCiAgICBFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gKGV2ZW50LCBmbikgewogICAgICBmdW5jdGlvbiBvbigpIHsKICAgICAgICB0aGlzLm9mZihldmVudCwgb24pOwogICAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgIH0KICAgICAgb24uZm4gPSBmbjsKICAgICAgdGhpcy5vbihldmVudCwgb24pOwogICAgICByZXR1cm4gdGhpczsKICAgIH07CgogICAgLyoqDQogICAgICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGwNCiAgICAgKiByZWdpc3RlcmVkIGNhbGxiYWNrcy4NCiAgICAgKg0KICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudA0KICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuDQogICAgICogQHJldHVybiB7RW1pdHRlcn0NCiAgICAgKiBAYXBpIHB1YmxpYw0KICAgICAqLwoKICAgIEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHsKICAgICAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9OwoKICAgICAgLy8gYWxsCiAgICAgIGlmICgwID09IGFyZ3VtZW50cy5sZW5ndGgpIHsKICAgICAgICB0aGlzLl9jYWxsYmFja3MgPSB7fTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLy8gc3BlY2lmaWMgZXZlbnQKICAgICAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF07CiAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpczsKCiAgICAgIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnMKICAgICAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkgewogICAgICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlcgogICAgICB2YXIgY2I7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgY2IgPSBjYWxsYmFja3NbaV07CiAgICAgICAgaWYgKGNiID09PSBmbiB8fCBjYi5mbiA9PT0gZm4pIHsKICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIFJlbW92ZSBldmVudCBzcGVjaWZpYyBhcnJheXMgZm9yIGV2ZW50IHR5cGVzIHRoYXQgbm8KICAgICAgLy8gb25lIGlzIHN1YnNjcmliZWQgZm9yIHRvIGF2b2lkIG1lbW9yeSBsZWFrLgogICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfTsKCiAgICAvKioNCiAgICAgKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy4NCiAgICAgKg0KICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudA0KICAgICAqIEBwYXJhbSB7TWl4ZWR9IC4uLg0KICAgICAqIEByZXR1cm4ge0VtaXR0ZXJ9DQogICAgICovCgogICAgRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkgewogICAgICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307CiAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKSwKICAgICAgICBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdOwogICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgewogICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldOwogICAgICB9CiAgICAgIGlmIChjYWxsYmFja3MpIHsKICAgICAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkgewogICAgICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH07CgogICAgLyoqDQogICAgICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC4NCiAgICAgKg0KICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudA0KICAgICAqIEByZXR1cm4ge0FycmF5fQ0KICAgICAqIEBhcGkgcHVibGljDQogICAgICovCgogICAgRW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTsKICAgICAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW107CiAgICB9OwoKICAgIC8qKg0KICAgICAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy4NCiAgICAgKg0KICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudA0KICAgICAqIEByZXR1cm4ge0Jvb2xlYW59DQogICAgICogQGFwaSBwdWJsaWMNCiAgICAgKi8KCiAgICBFbWl0dGVyLnByb3RvdHlwZS5oYXNMaXN0ZW5lcnMgPSBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgcmV0dXJuICEhdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDsKICAgIH07CiAgfSkoY29tcG9uZW50RW1pdHRlcik7CgogIC8qKgogICAqIEV4cG9zZSBgQmFja29mZmAuCiAgICovCgogIHZhciBiYWNrbzIgPSBCYWNrb2ZmOwoKICAvKioKICAgKiBJbml0aWFsaXplIGJhY2tvZmYgdGltZXIgd2l0aCBgb3B0c2AuCiAgICoKICAgKiAtIGBtaW5gIGluaXRpYWwgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgWzEwMF0KICAgKiAtIGBtYXhgIG1heCB0aW1lb3V0IFsxMDAwMF0KICAgKiAtIGBqaXR0ZXJgIFswXQogICAqIC0gYGZhY3RvcmAgWzJdCiAgICoKICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cwogICAqIEBhcGkgcHVibGljCiAgICovCgogIGZ1bmN0aW9uIEJhY2tvZmYob3B0cykgewogICAgb3B0cyA9IG9wdHMgfHwge307CiAgICB0aGlzLm1zID0gb3B0cy5taW4gfHwgMTAwOwogICAgdGhpcy5tYXggPSBvcHRzLm1heCB8fCAxMDAwMDsKICAgIHRoaXMuZmFjdG9yID0gb3B0cy5mYWN0b3IgfHwgMjsKICAgIHRoaXMuaml0dGVyID0gb3B0cy5qaXR0ZXIgPiAwICYmIG9wdHMuaml0dGVyIDw9IDEgPyBvcHRzLmppdHRlciA6IDA7CiAgICB0aGlzLmF0dGVtcHRzID0gMDsKICB9CgogIC8qKgogICAqIFJldHVybiB0aGUgYmFja29mZiBkdXJhdGlvbi4KICAgKgogICAqIEByZXR1cm4ge051bWJlcn0KICAgKiBAYXBpIHB1YmxpYwogICAqLwoKICBCYWNrb2ZmLnByb3RvdHlwZS5kdXJhdGlvbiA9IGZ1bmN0aW9uICgpIHsKICAgIHZhciBtcyA9IHRoaXMubXMgKiBNYXRoLnBvdyh0aGlzLmZhY3RvciwgdGhpcy5hdHRlbXB0cysrKTsKICAgIGlmICh0aGlzLmppdHRlcikgewogICAgICB2YXIgcmFuZCA9IE1hdGgucmFuZG9tKCk7CiAgICAgIHZhciBkZXZpYXRpb24gPSBNYXRoLmZsb29yKHJhbmQgKiB0aGlzLmppdHRlciAqIG1zKTsKICAgICAgbXMgPSAoTWF0aC5mbG9vcihyYW5kICogMTApICYgMSkgPT0gMCA/IG1zIC0gZGV2aWF0aW9uIDogbXMgKyBkZXZpYXRpb247CiAgICB9CiAgICByZXR1cm4gTWF0aC5taW4obXMsIHRoaXMubWF4KSB8IDA7CiAgfTsKCiAgLyoqCiAgICogUmVzZXQgdGhlIG51bWJlciBvZiBhdHRlbXB0cy4KICAgKgogICAqIEBhcGkgcHVibGljCiAgICovCgogIEJhY2tvZmYucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkgewogICAgdGhpcy5hdHRlbXB0cyA9IDA7CiAgfTsKCiAgLyoqCiAgICogU2V0IHRoZSBtaW5pbXVtIGR1cmF0aW9uCiAgICoKICAgKiBAYXBpIHB1YmxpYwogICAqLwoKICBCYWNrb2ZmLnByb3RvdHlwZS5zZXRNaW4gPSBmdW5jdGlvbiAobWluKSB7CiAgICB0aGlzLm1zID0gbWluOwogIH07CgogIC8qKgogICAqIFNldCB0aGUgbWF4aW11bSBkdXJhdGlvbgogICAqCiAgICogQGFwaSBwdWJsaWMKICAgKi8KCiAgQmFja29mZi5wcm90b3R5cGUuc2V0TWF4ID0gZnVuY3Rpb24gKG1heCkgewogICAgdGhpcy5tYXggPSBtYXg7CiAgfTsKCiAgLyoqCiAgICogU2V0IHRoZSBqaXR0ZXIKICAgKgogICAqIEBhcGkgcHVibGljCiAgICovCgogIEJhY2tvZmYucHJvdG90eXBlLnNldEppdHRlciA9IGZ1bmN0aW9uIChqaXR0ZXIpIHsKICAgIHRoaXMuaml0dGVyID0gaml0dGVyOwogIH07CgogIHZhciBwYWtvJDEgPSB7fTsKCiAgdmFyIGRlZmxhdGUkNCA9IHt9OwoKICB2YXIgZGVmbGF0ZSQzID0ge307CgogIHZhciB0cmVlcyA9IHt9OwoKICAvLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXIKICAvLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpbgogIC8vCiAgLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICAvLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKICAvLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogIC8vCiAgLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiAgLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogIC8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKICAvLwogIC8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAgLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZQogIC8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiAgLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogIC8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiAgLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAgLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KCiAgLyogZXNsaW50LWRpc2FibGUgc3BhY2UtdW5hcnktb3BzICovCgogIC8qIFB1YmxpYyBjb25zdGFudHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KCiAgLy9jb25zdCBaX0ZJTFRFUkVEICAgICAgICAgID0gMTsKICAvL2NvbnN0IFpfSFVGRk1BTl9PTkxZICAgICAgPSAyOwogIC8vY29uc3QgWl9STEUgICAgICAgICAgICAgICA9IDM7CiAgdmFyIFpfRklYRUQkMSA9IDQ7CiAgLy9jb25zdCBaX0RFRkFVTFRfU1RSQVRFR1kgID0gMDsKCiAgLyogUG9zc2libGUgdmFsdWVzIG9mIHRoZSBkYXRhX3R5cGUgZmllbGQgKHRob3VnaCBzZWUgaW5mbGF0ZSgpKSAqLwogIHZhciBaX0JJTkFSWSA9IDA7CiAgdmFyIFpfVEVYVCA9IDE7CiAgLy9jb25zdCBaX0FTQ0lJICAgICAgICAgICAgID0gMTsgLy8gPSBaX1RFWFQKICB2YXIgWl9VTktOT1dOJDEgPSAyOwoKICAvKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKICBmdW5jdGlvbiB6ZXJvJDEoYnVmKSB7CiAgICB2YXIgbGVuID0gYnVmLmxlbmd0aDsKICAgIHdoaWxlICgtLWxlbiA+PSAwKSB7CiAgICAgIGJ1ZltsZW5dID0gMDsKICAgIH0KICB9CgogIC8vIEZyb20genV0aWwuaAoKICB2YXIgU1RPUkVEX0JMT0NLID0gMDsKICB2YXIgU1RBVElDX1RSRUVTID0gMTsKICB2YXIgRFlOX1RSRUVTID0gMjsKICAvKiBUaGUgdGhyZWUga2luZHMgb2YgYmxvY2sgdHlwZSAqLwoKICB2YXIgTUlOX01BVENIJDEgPSAzOwogIHZhciBNQVhfTUFUQ0gkMSA9IDI1ODsKICAvKiBUaGUgbWluaW11bSBhbmQgbWF4aW11bSBtYXRjaCBsZW5ndGhzICovCgogIC8vIEZyb20gZGVmbGF0ZS5oCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogSW50ZXJuYWwgY29tcHJlc3Npb24gc3RhdGUuCiAgICovCgogIHZhciBMRU5HVEhfQ09ERVMkMSA9IDI5OwogIC8qIG51bWJlciBvZiBsZW5ndGggY29kZXMsIG5vdCBjb3VudGluZyB0aGUgc3BlY2lhbCBFTkRfQkxPQ0sgY29kZSAqLwoKICB2YXIgTElURVJBTFMkMSA9IDI1NjsKICAvKiBudW1iZXIgb2YgbGl0ZXJhbCBieXRlcyAwLi4yNTUgKi8KCiAgdmFyIExfQ09ERVMkMSA9IExJVEVSQUxTJDEgKyAxICsgTEVOR1RIX0NPREVTJDE7CiAgLyogbnVtYmVyIG9mIExpdGVyYWwgb3IgTGVuZ3RoIGNvZGVzLCBpbmNsdWRpbmcgdGhlIEVORF9CTE9DSyBjb2RlICovCgogIHZhciBEX0NPREVTJDEgPSAzMDsKICAvKiBudW1iZXIgb2YgZGlzdGFuY2UgY29kZXMgKi8KCiAgdmFyIEJMX0NPREVTJDEgPSAxOTsKICAvKiBudW1iZXIgb2YgY29kZXMgdXNlZCB0byB0cmFuc2ZlciB0aGUgYml0IGxlbmd0aHMgKi8KCiAgdmFyIEhFQVBfU0laRSQxID0gMiAqIExfQ09ERVMkMSArIDE7CiAgLyogbWF4aW11bSBoZWFwIHNpemUgKi8KCiAgdmFyIE1BWF9CSVRTJDEgPSAxNTsKICAvKiBBbGwgY29kZXMgbXVzdCBub3QgZXhjZWVkIE1BWF9CSVRTIGJpdHMgKi8KCiAgdmFyIEJ1Zl9zaXplID0gMTY7CiAgLyogc2l6ZSBvZiBiaXQgYnVmZmVyIGluIGJpX2J1ZiAqLwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBDb25zdGFudHMKICAgKi8KCiAgdmFyIE1BWF9CTF9CSVRTID0gNzsKICAvKiBCaXQgbGVuZ3RoIGNvZGVzIG11c3Qgbm90IGV4Y2VlZCBNQVhfQkxfQklUUyBiaXRzICovCgogIHZhciBFTkRfQkxPQ0sgPSAyNTY7CiAgLyogZW5kIG9mIGJsb2NrIGxpdGVyYWwgY29kZSAqLwoKICB2YXIgUkVQXzNfNiA9IDE2OwogIC8qIHJlcGVhdCBwcmV2aW91cyBiaXQgbGVuZ3RoIDMtNiB0aW1lcyAoMiBiaXRzIG9mIHJlcGVhdCBjb3VudCkgKi8KCiAgdmFyIFJFUFpfM18xMCA9IDE3OwogIC8qIHJlcGVhdCBhIHplcm8gbGVuZ3RoIDMtMTAgdGltZXMgICgzIGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqLwoKICB2YXIgUkVQWl8xMV8xMzggPSAxODsKICAvKiByZXBlYXQgYSB6ZXJvIGxlbmd0aCAxMS0xMzggdGltZXMgICg3IGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqLwoKICAvKiBlc2xpbnQtZGlzYWJsZSBjb21tYS1zcGFjaW5nLGFycmF5LWJyYWNrZXQtc3BhY2luZyAqLwogIHZhciBleHRyYV9sYml0cyA9IC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggbGVuZ3RoIGNvZGUgKi8KICBuZXcgVWludDhBcnJheShbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMiwgMiwgMiwgMiwgMywgMywgMywgMywgNCwgNCwgNCwgNCwgNSwgNSwgNSwgNSwgMF0pOwogIHZhciBleHRyYV9kYml0cyA9IC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggZGlzdGFuY2UgY29kZSAqLwogIG5ldyBVaW50OEFycmF5KFswLCAwLCAwLCAwLCAxLCAxLCAyLCAyLCAzLCAzLCA0LCA0LCA1LCA1LCA2LCA2LCA3LCA3LCA4LCA4LCA5LCA5LCAxMCwgMTAsIDExLCAxMSwgMTIsIDEyLCAxMywgMTNdKTsKICB2YXIgZXh0cmFfYmxiaXRzID0gLyogZXh0cmEgYml0cyBmb3IgZWFjaCBiaXQgbGVuZ3RoIGNvZGUgKi8KICBuZXcgVWludDhBcnJheShbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMiwgMywgN10pOwogIHZhciBibF9vcmRlciA9IG5ldyBVaW50OEFycmF5KFsxNiwgMTcsIDE4LCAwLCA4LCA3LCA5LCA2LCAxMCwgNSwgMTEsIDQsIDEyLCAzLCAxMywgMiwgMTQsIDEsIDE1XSk7CiAgLyogZXNsaW50LWVuYWJsZSBjb21tYS1zcGFjaW5nLGFycmF5LWJyYWNrZXQtc3BhY2luZyAqLwoKICAvKiBUaGUgbGVuZ3RocyBvZiB0aGUgYml0IGxlbmd0aCBjb2RlcyBhcmUgc2VudCBpbiBvcmRlciBvZiBkZWNyZWFzaW5nCiAgICogcHJvYmFiaWxpdHksIHRvIGF2b2lkIHRyYW5zbWl0dGluZyB0aGUgbGVuZ3RocyBmb3IgdW51c2VkIGJpdCBsZW5ndGggY29kZXMuCiAgICovCgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIExvY2FsIGRhdGEuIFRoZXNlIGFyZSBpbml0aWFsaXplZCBvbmx5IG9uY2UuCiAgICovCgogIC8vIFdlIHByZS1maWxsIGFycmF5cyB3aXRoIDAgdG8gYXZvaWQgdW5pbml0aWFsaXplZCBnYXBzCgogIHZhciBESVNUX0NPREVfTEVOID0gNTEyOyAvKiBzZWUgZGVmaW5pdGlvbiBvZiBhcnJheSBkaXN0X2NvZGUgYmVsb3cgKi8KCiAgLy8gISEhISBVc2UgZmxhdCBhcnJheSBpbnN0ZWFkIG9mIHN0cnVjdHVyZSwgRnJlcSA9IGkqMiwgTGVuID0gaSoyKzEKICB2YXIgc3RhdGljX2x0cmVlID0gbmV3IEFycmF5KChMX0NPREVTJDEgKyAyKSAqIDIpOwogIHplcm8kMShzdGF0aWNfbHRyZWUpOwogIC8qIFRoZSBzdGF0aWMgbGl0ZXJhbCB0cmVlLiBTaW5jZSB0aGUgYml0IGxlbmd0aHMgYXJlIGltcG9zZWQsIHRoZXJlIGlzIG5vCiAgICogbmVlZCBmb3IgdGhlIExfQ09ERVMgZXh0cmEgY29kZXMgdXNlZCBkdXJpbmcgaGVhcCBjb25zdHJ1Y3Rpb24uIEhvd2V2ZXIKICAgKiBUaGUgY29kZXMgMjg2IGFuZCAyODcgYXJlIG5lZWRlZCB0byBidWlsZCBhIGNhbm9uaWNhbCB0cmVlIChzZWUgX3RyX2luaXQKICAgKiBiZWxvdykuCiAgICovCgogIHZhciBzdGF0aWNfZHRyZWUgPSBuZXcgQXJyYXkoRF9DT0RFUyQxICogMik7CiAgemVybyQxKHN0YXRpY19kdHJlZSk7CiAgLyogVGhlIHN0YXRpYyBkaXN0YW5jZSB0cmVlLiAoQWN0dWFsbHkgYSB0cml2aWFsIHRyZWUgc2luY2UgYWxsIGNvZGVzIHVzZQogICAqIDUgYml0cy4pCiAgICovCgogIHZhciBfZGlzdF9jb2RlID0gbmV3IEFycmF5KERJU1RfQ09ERV9MRU4pOwogIHplcm8kMShfZGlzdF9jb2RlKTsKICAvKiBEaXN0YW5jZSBjb2Rlcy4gVGhlIGZpcnN0IDI1NiB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUgZGlzdGFuY2VzCiAgICogMyAuLiAyNTgsIHRoZSBsYXN0IDI1NiB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUgdG9wIDggYml0cyBvZgogICAqIHRoZSAxNSBiaXQgZGlzdGFuY2VzLgogICAqLwoKICB2YXIgX2xlbmd0aF9jb2RlID0gbmV3IEFycmF5KE1BWF9NQVRDSCQxIC0gTUlOX01BVENIJDEgKyAxKTsKICB6ZXJvJDEoX2xlbmd0aF9jb2RlKTsKICAvKiBsZW5ndGggY29kZSBmb3IgZWFjaCBub3JtYWxpemVkIG1hdGNoIGxlbmd0aCAoMCA9PSBNSU5fTUFUQ0gpICovCgogIHZhciBiYXNlX2xlbmd0aCA9IG5ldyBBcnJheShMRU5HVEhfQ09ERVMkMSk7CiAgemVybyQxKGJhc2VfbGVuZ3RoKTsKICAvKiBGaXJzdCBub3JtYWxpemVkIGxlbmd0aCBmb3IgZWFjaCBjb2RlICgwID0gTUlOX01BVENIKSAqLwoKICB2YXIgYmFzZV9kaXN0ID0gbmV3IEFycmF5KERfQ09ERVMkMSk7CiAgemVybyQxKGJhc2VfZGlzdCk7CiAgLyogRmlyc3Qgbm9ybWFsaXplZCBkaXN0YW5jZSBmb3IgZWFjaCBjb2RlICgwID0gZGlzdGFuY2Ugb2YgMSkgKi8KCiAgZnVuY3Rpb24gU3RhdGljVHJlZURlc2Moc3RhdGljX3RyZWUsIGV4dHJhX2JpdHMsIGV4dHJhX2Jhc2UsIGVsZW1zLCBtYXhfbGVuZ3RoKSB7CiAgICB0aGlzLnN0YXRpY190cmVlID0gc3RhdGljX3RyZWU7IC8qIHN0YXRpYyB0cmVlIG9yIE5VTEwgKi8KICAgIHRoaXMuZXh0cmFfYml0cyA9IGV4dHJhX2JpdHM7IC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggY29kZSBvciBOVUxMICovCiAgICB0aGlzLmV4dHJhX2Jhc2UgPSBleHRyYV9iYXNlOyAvKiBiYXNlIGluZGV4IGZvciBleHRyYV9iaXRzICovCiAgICB0aGlzLmVsZW1zID0gZWxlbXM7IC8qIG1heCBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHRyZWUgKi8KICAgIHRoaXMubWF4X2xlbmd0aCA9IG1heF9sZW5ndGg7IC8qIG1heCBiaXQgbGVuZ3RoIGZvciB0aGUgY29kZXMgKi8KCiAgICAvLyBzaG93IGlmIGBzdGF0aWNfdHJlZWAgaGFzIGRhdGEgb3IgZHVtbXkgLSBuZWVkZWQgZm9yIG1vbm9tb3JwaGljIG9iamVjdHMKICAgIHRoaXMuaGFzX3N0cmVlID0gc3RhdGljX3RyZWUgJiYgc3RhdGljX3RyZWUubGVuZ3RoOwogIH0KICB2YXIgc3RhdGljX2xfZGVzYzsKICB2YXIgc3RhdGljX2RfZGVzYzsKICB2YXIgc3RhdGljX2JsX2Rlc2M7CiAgZnVuY3Rpb24gVHJlZURlc2MoZHluX3RyZWUsIHN0YXRfZGVzYykgewogICAgdGhpcy5keW5fdHJlZSA9IGR5bl90cmVlOyAvKiB0aGUgZHluYW1pYyB0cmVlICovCiAgICB0aGlzLm1heF9jb2RlID0gMDsgLyogbGFyZ2VzdCBjb2RlIHdpdGggbm9uIHplcm8gZnJlcXVlbmN5ICovCiAgICB0aGlzLnN0YXRfZGVzYyA9IHN0YXRfZGVzYzsgLyogdGhlIGNvcnJlc3BvbmRpbmcgc3RhdGljIHRyZWUgKi8KICB9CiAgdmFyIGRfY29kZSA9IGZ1bmN0aW9uIGRfY29kZShkaXN0KSB7CiAgICByZXR1cm4gZGlzdCA8IDI1NiA/IF9kaXN0X2NvZGVbZGlzdF0gOiBfZGlzdF9jb2RlWzI1NiArIChkaXN0ID4+PiA3KV07CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogT3V0cHV0IGEgc2hvcnQgTFNCIGZpcnN0IG9uIHRoZSBzdHJlYW0uCiAgICogSU4gYXNzZXJ0aW9uOiB0aGVyZSBpcyBlbm91Z2ggcm9vbSBpbiBwZW5kaW5nQnVmLgogICAqLwogIHZhciBwdXRfc2hvcnQgPSBmdW5jdGlvbiBwdXRfc2hvcnQocywgdykgewogICAgLy8gICAgcHV0X2J5dGUocywgKHVjaCkoKHcpICYgMHhmZikpOwogICAgLy8gICAgcHV0X2J5dGUocywgKHVjaCkoKHVzaCkodykgPj4gOCkpOwogICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSB3ICYgMHhmZjsKICAgIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gdyA+Pj4gOCAmIDB4ZmY7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogU2VuZCBhIHZhbHVlIG9uIGEgZ2l2ZW4gbnVtYmVyIG9mIGJpdHMuCiAgICogSU4gYXNzZXJ0aW9uOiBsZW5ndGggPD0gMTYgYW5kIHZhbHVlIGZpdHMgaW4gbGVuZ3RoIGJpdHMuCiAgICovCiAgdmFyIHNlbmRfYml0cyA9IGZ1bmN0aW9uIHNlbmRfYml0cyhzLCB2YWx1ZSwgbGVuZ3RoKSB7CiAgICBpZiAocy5iaV92YWxpZCA+IEJ1Zl9zaXplIC0gbGVuZ3RoKSB7CiAgICAgIHMuYmlfYnVmIHw9IHZhbHVlIDw8IHMuYmlfdmFsaWQgJiAweGZmZmY7CiAgICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7CiAgICAgIHMuYmlfYnVmID0gdmFsdWUgPj4gQnVmX3NpemUgLSBzLmJpX3ZhbGlkOwogICAgICBzLmJpX3ZhbGlkICs9IGxlbmd0aCAtIEJ1Zl9zaXplOwogICAgfSBlbHNlIHsKICAgICAgcy5iaV9idWYgfD0gdmFsdWUgPDwgcy5iaV92YWxpZCAmIDB4ZmZmZjsKICAgICAgcy5iaV92YWxpZCArPSBsZW5ndGg7CiAgICB9CiAgfTsKICB2YXIgc2VuZF9jb2RlID0gZnVuY3Rpb24gc2VuZF9jb2RlKHMsIGMsIHRyZWUpIHsKICAgIHNlbmRfYml0cyhzLCB0cmVlW2MgKiAyXSAvKi5Db2RlKi8sIHRyZWVbYyAqIDIgKyAxXSAvKi5MZW4qLyk7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogUmV2ZXJzZSB0aGUgZmlyc3QgbGVuIGJpdHMgb2YgYSBjb2RlLCB1c2luZyBzdHJhaWdodGZvcndhcmQgY29kZSAoYSBmYXN0ZXIKICAgKiBtZXRob2Qgd291bGQgdXNlIGEgdGFibGUpCiAgICogSU4gYXNzZXJ0aW9uOiAxIDw9IGxlbiA8PSAxNQogICAqLwogIHZhciBiaV9yZXZlcnNlID0gZnVuY3Rpb24gYmlfcmV2ZXJzZShjb2RlLCBsZW4pIHsKICAgIHZhciByZXMgPSAwOwogICAgZG8gewogICAgICByZXMgfD0gY29kZSAmIDE7CiAgICAgIGNvZGUgPj4+PSAxOwogICAgICByZXMgPDw9IDE7CiAgICB9IHdoaWxlICgtLWxlbiA+IDApOwogICAgcmV0dXJuIHJlcyA+Pj4gMTsKICB9OwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBGbHVzaCB0aGUgYml0IGJ1ZmZlciwga2VlcGluZyBhdCBtb3N0IDcgYml0cyBpbiBpdC4KICAgKi8KICB2YXIgYmlfZmx1c2ggPSBmdW5jdGlvbiBiaV9mbHVzaChzKSB7CiAgICBpZiAocy5iaV92YWxpZCA9PT0gMTYpIHsKICAgICAgcHV0X3Nob3J0KHMsIHMuYmlfYnVmKTsKICAgICAgcy5iaV9idWYgPSAwOwogICAgICBzLmJpX3ZhbGlkID0gMDsKICAgIH0gZWxzZSBpZiAocy5iaV92YWxpZCA+PSA4KSB7CiAgICAgIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gcy5iaV9idWYgJiAweGZmOwogICAgICBzLmJpX2J1ZiA+Pj0gODsKICAgICAgcy5iaV92YWxpZCAtPSA4OwogICAgfQogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIENvbXB1dGUgdGhlIG9wdGltYWwgYml0IGxlbmd0aHMgZm9yIGEgdHJlZSBhbmQgdXBkYXRlIHRoZSB0b3RhbCBiaXQgbGVuZ3RoCiAgICogZm9yIHRoZSBjdXJyZW50IGJsb2NrLgogICAqIElOIGFzc2VydGlvbjogdGhlIGZpZWxkcyBmcmVxIGFuZCBkYWQgYXJlIHNldCwgaGVhcFtoZWFwX21heF0gYW5kCiAgICogICAgYWJvdmUgYXJlIHRoZSB0cmVlIG5vZGVzIHNvcnRlZCBieSBpbmNyZWFzaW5nIGZyZXF1ZW5jeS4KICAgKiBPVVQgYXNzZXJ0aW9uczogdGhlIGZpZWxkIGxlbiBpcyBzZXQgdG8gdGhlIG9wdGltYWwgYml0IGxlbmd0aCwgdGhlCiAgICogICAgIGFycmF5IGJsX2NvdW50IGNvbnRhaW5zIHRoZSBmcmVxdWVuY2llcyBmb3IgZWFjaCBiaXQgbGVuZ3RoLgogICAqICAgICBUaGUgbGVuZ3RoIG9wdF9sZW4gaXMgdXBkYXRlZDsgc3RhdGljX2xlbiBpcyBhbHNvIHVwZGF0ZWQgaWYgc3RyZWUgaXMKICAgKiAgICAgbm90IG51bGwuCiAgICovCiAgdmFyIGdlbl9iaXRsZW4gPSBmdW5jdGlvbiBnZW5fYml0bGVuKHMsIGRlc2MpCiAgLy8gICAgZGVmbGF0ZV9zdGF0ZSAqczsKICAvLyAgICB0cmVlX2Rlc2MgKmRlc2M7ICAgIC8qIHRoZSB0cmVlIGRlc2NyaXB0b3IgKi8KICB7CiAgICB2YXIgdHJlZSA9IGRlc2MuZHluX3RyZWU7CiAgICB2YXIgbWF4X2NvZGUgPSBkZXNjLm1heF9jb2RlOwogICAgdmFyIHN0cmVlID0gZGVzYy5zdGF0X2Rlc2Muc3RhdGljX3RyZWU7CiAgICB2YXIgaGFzX3N0cmVlID0gZGVzYy5zdGF0X2Rlc2MuaGFzX3N0cmVlOwogICAgdmFyIGV4dHJhID0gZGVzYy5zdGF0X2Rlc2MuZXh0cmFfYml0czsKICAgIHZhciBiYXNlID0gZGVzYy5zdGF0X2Rlc2MuZXh0cmFfYmFzZTsKICAgIHZhciBtYXhfbGVuZ3RoID0gZGVzYy5zdGF0X2Rlc2MubWF4X2xlbmd0aDsKICAgIHZhciBoOyAvKiBoZWFwIGluZGV4ICovCiAgICB2YXIgbiwgbTsgLyogaXRlcmF0ZSBvdmVyIHRoZSB0cmVlIGVsZW1lbnRzICovCiAgICB2YXIgYml0czsgLyogYml0IGxlbmd0aCAqLwogICAgdmFyIHhiaXRzOyAvKiBleHRyYSBiaXRzICovCiAgICB2YXIgZjsgLyogZnJlcXVlbmN5ICovCiAgICB2YXIgb3ZlcmZsb3cgPSAwOyAvKiBudW1iZXIgb2YgZWxlbWVudHMgd2l0aCBiaXQgbGVuZ3RoIHRvbyBsYXJnZSAqLwoKICAgIGZvciAoYml0cyA9IDA7IGJpdHMgPD0gTUFYX0JJVFMkMTsgYml0cysrKSB7CiAgICAgIHMuYmxfY291bnRbYml0c10gPSAwOwogICAgfQoKICAgIC8qIEluIGEgZmlyc3QgcGFzcywgY29tcHV0ZSB0aGUgb3B0aW1hbCBiaXQgbGVuZ3RocyAod2hpY2ggbWF5CiAgICAgKiBvdmVyZmxvdyBpbiB0aGUgY2FzZSBvZiB0aGUgYml0IGxlbmd0aCB0cmVlKS4KICAgICAqLwogICAgdHJlZVtzLmhlYXBbcy5oZWFwX21heF0gKiAyICsgMV0gLyouTGVuKi8gPSAwOyAvKiByb290IG9mIHRoZSBoZWFwICovCgogICAgZm9yIChoID0gcy5oZWFwX21heCArIDE7IGggPCBIRUFQX1NJWkUkMTsgaCsrKSB7CiAgICAgIG4gPSBzLmhlYXBbaF07CiAgICAgIGJpdHMgPSB0cmVlW3RyZWVbbiAqIDIgKyAxXSAvKi5EYWQqLyAqIDIgKyAxXSAvKi5MZW4qLyArIDE7CiAgICAgIGlmIChiaXRzID4gbWF4X2xlbmd0aCkgewogICAgICAgIGJpdHMgPSBtYXhfbGVuZ3RoOwogICAgICAgIG92ZXJmbG93Kys7CiAgICAgIH0KICAgICAgdHJlZVtuICogMiArIDFdIC8qLkxlbiovID0gYml0czsKICAgICAgLyogV2Ugb3ZlcndyaXRlIHRyZWVbbl0uRGFkIHdoaWNoIGlzIG5vIGxvbmdlciBuZWVkZWQgKi8KCiAgICAgIGlmIChuID4gbWF4X2NvZGUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfSAvKiBub3QgYSBsZWFmIG5vZGUgKi8KCiAgICAgIHMuYmxfY291bnRbYml0c10rKzsKICAgICAgeGJpdHMgPSAwOwogICAgICBpZiAobiA+PSBiYXNlKSB7CiAgICAgICAgeGJpdHMgPSBleHRyYVtuIC0gYmFzZV07CiAgICAgIH0KICAgICAgZiA9IHRyZWVbbiAqIDJdIC8qLkZyZXEqLzsKICAgICAgcy5vcHRfbGVuICs9IGYgKiAoYml0cyArIHhiaXRzKTsKICAgICAgaWYgKGhhc19zdHJlZSkgewogICAgICAgIHMuc3RhdGljX2xlbiArPSBmICogKHN0cmVlW24gKiAyICsgMV0gLyouTGVuKi8gKyB4Yml0cyk7CiAgICAgIH0KICAgIH0KICAgIGlmIChvdmVyZmxvdyA9PT0gMCkgewogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVHJhY2UoKHN0ZGVyciwiXG5iaXQgbGVuZ3RoIG92ZXJmbG93XG4iKSk7CiAgICAvKiBUaGlzIGhhcHBlbnMgZm9yIGV4YW1wbGUgb24gb2JqMiBhbmQgcGljIG9mIHRoZSBDYWxnYXJ5IGNvcnB1cyAqLwoKICAgIC8qIEZpbmQgdGhlIGZpcnN0IGJpdCBsZW5ndGggd2hpY2ggY291bGQgaW5jcmVhc2U6ICovCiAgICBkbyB7CiAgICAgIGJpdHMgPSBtYXhfbGVuZ3RoIC0gMTsKICAgICAgd2hpbGUgKHMuYmxfY291bnRbYml0c10gPT09IDApIHsKICAgICAgICBiaXRzLS07CiAgICAgIH0KICAgICAgcy5ibF9jb3VudFtiaXRzXS0tOyAvKiBtb3ZlIG9uZSBsZWFmIGRvd24gdGhlIHRyZWUgKi8KICAgICAgcy5ibF9jb3VudFtiaXRzICsgMV0gKz0gMjsgLyogbW92ZSBvbmUgb3ZlcmZsb3cgaXRlbSBhcyBpdHMgYnJvdGhlciAqLwogICAgICBzLmJsX2NvdW50W21heF9sZW5ndGhdLS07CiAgICAgIC8qIFRoZSBicm90aGVyIG9mIHRoZSBvdmVyZmxvdyBpdGVtIGFsc28gbW92ZXMgb25lIHN0ZXAgdXAsCiAgICAgICAqIGJ1dCB0aGlzIGRvZXMgbm90IGFmZmVjdCBibF9jb3VudFttYXhfbGVuZ3RoXQogICAgICAgKi8KICAgICAgb3ZlcmZsb3cgLT0gMjsKICAgIH0gd2hpbGUgKG92ZXJmbG93ID4gMCk7CgogICAgLyogTm93IHJlY29tcHV0ZSBhbGwgYml0IGxlbmd0aHMsIHNjYW5uaW5nIGluIGluY3JlYXNpbmcgZnJlcXVlbmN5LgogICAgICogaCBpcyBzdGlsbCBlcXVhbCB0byBIRUFQX1NJWkUuIChJdCBpcyBzaW1wbGVyIHRvIHJlY29uc3RydWN0IGFsbAogICAgICogbGVuZ3RocyBpbnN0ZWFkIG9mIGZpeGluZyBvbmx5IHRoZSB3cm9uZyBvbmVzLiBUaGlzIGlkZWEgaXMgdGFrZW4KICAgICAqIGZyb20gJ2FyJyB3cml0dGVuIGJ5IEhhcnVoaWtvIE9rdW11cmEuKQogICAgICovCiAgICBmb3IgKGJpdHMgPSBtYXhfbGVuZ3RoOyBiaXRzICE9PSAwOyBiaXRzLS0pIHsKICAgICAgbiA9IHMuYmxfY291bnRbYml0c107CiAgICAgIHdoaWxlIChuICE9PSAwKSB7CiAgICAgICAgbSA9IHMuaGVhcFstLWhdOwogICAgICAgIGlmIChtID4gbWF4X2NvZGUpIHsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAodHJlZVttICogMiArIDFdIC8qLkxlbiovICE9PSBiaXRzKSB7CiAgICAgICAgICAvLyBUcmFjZSgoc3RkZXJyLCJjb2RlICVkIGJpdHMgJWQtPiVkXG4iLCBtLCB0cmVlW21dLkxlbiwgYml0cykpOwogICAgICAgICAgcy5vcHRfbGVuICs9IChiaXRzIC0gdHJlZVttICogMiArIDFdIC8qLkxlbiovKSAqIHRyZWVbbSAqIDJdIC8qLkZyZXEqLzsKICAgICAgICAgIHRyZWVbbSAqIDIgKyAxXSAvKi5MZW4qLyA9IGJpdHM7CiAgICAgICAgfQogICAgICAgIG4tLTsKICAgICAgfQogICAgfQogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIEdlbmVyYXRlIHRoZSBjb2RlcyBmb3IgYSBnaXZlbiB0cmVlIGFuZCBiaXQgY291bnRzICh3aGljaCBuZWVkIG5vdCBiZQogICAqIG9wdGltYWwpLgogICAqIElOIGFzc2VydGlvbjogdGhlIGFycmF5IGJsX2NvdW50IGNvbnRhaW5zIHRoZSBiaXQgbGVuZ3RoIHN0YXRpc3RpY3MgZm9yCiAgICogdGhlIGdpdmVuIHRyZWUgYW5kIHRoZSBmaWVsZCBsZW4gaXMgc2V0IGZvciBhbGwgdHJlZSBlbGVtZW50cy4KICAgKiBPVVQgYXNzZXJ0aW9uOiB0aGUgZmllbGQgY29kZSBpcyBzZXQgZm9yIGFsbCB0cmVlIGVsZW1lbnRzIG9mIG5vbgogICAqICAgICB6ZXJvIGNvZGUgbGVuZ3RoLgogICAqLwogIHZhciBnZW5fY29kZXMgPSBmdW5jdGlvbiBnZW5fY29kZXModHJlZSwgbWF4X2NvZGUsIGJsX2NvdW50KQogIC8vICAgIGN0X2RhdGEgKnRyZWU7ICAgICAgICAgICAgIC8qIHRoZSB0cmVlIHRvIGRlY29yYXRlICovCiAgLy8gICAgaW50IG1heF9jb2RlOyAgICAgICAgICAgICAgLyogbGFyZ2VzdCBjb2RlIHdpdGggbm9uIHplcm8gZnJlcXVlbmN5ICovCiAgLy8gICAgdXNoZiAqYmxfY291bnQ7ICAgICAgICAgICAgLyogbnVtYmVyIG9mIGNvZGVzIGF0IGVhY2ggYml0IGxlbmd0aCAqLwogIHsKICAgIHZhciBuZXh0X2NvZGUgPSBuZXcgQXJyYXkoTUFYX0JJVFMkMSArIDEpOyAvKiBuZXh0IGNvZGUgdmFsdWUgZm9yIGVhY2ggYml0IGxlbmd0aCAqLwogICAgdmFyIGNvZGUgPSAwOyAvKiBydW5uaW5nIGNvZGUgdmFsdWUgKi8KICAgIHZhciBiaXRzOyAvKiBiaXQgaW5kZXggKi8KICAgIHZhciBuOyAvKiBjb2RlIGluZGV4ICovCgogICAgLyogVGhlIGRpc3RyaWJ1dGlvbiBjb3VudHMgYXJlIGZpcnN0IHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGNvZGUgdmFsdWVzCiAgICAgKiB3aXRob3V0IGJpdCByZXZlcnNhbC4KICAgICAqLwogICAgZm9yIChiaXRzID0gMTsgYml0cyA8PSBNQVhfQklUUyQxOyBiaXRzKyspIHsKICAgICAgbmV4dF9jb2RlW2JpdHNdID0gY29kZSA9IGNvZGUgKyBibF9jb3VudFtiaXRzIC0gMV0gPDwgMTsKICAgIH0KICAgIC8qIENoZWNrIHRoYXQgdGhlIGJpdCBjb3VudHMgaW4gYmxfY291bnQgYXJlIGNvbnNpc3RlbnQuIFRoZSBsYXN0IGNvZGUKICAgICAqIG11c3QgYmUgYWxsIG9uZXMuCiAgICAgKi8KICAgIC8vQXNzZXJ0IChjb2RlICsgYmxfY291bnRbTUFYX0JJVFNdLTEgPT0gKDE8PE1BWF9CSVRTKS0xLAogICAgLy8gICAgICAgICJpbmNvbnNpc3RlbnQgYml0IGNvdW50cyIpOwogICAgLy9UcmFjZXYoKHN0ZGVyciwiXG5nZW5fY29kZXM6IG1heF9jb2RlICVkICIsIG1heF9jb2RlKSk7CgogICAgZm9yIChuID0gMDsgbiA8PSBtYXhfY29kZTsgbisrKSB7CiAgICAgIHZhciBsZW4gPSB0cmVlW24gKiAyICsgMV0gLyouTGVuKi87CiAgICAgIGlmIChsZW4gPT09IDApIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICAvKiBOb3cgcmV2ZXJzZSB0aGUgYml0cyAqLwogICAgICB0cmVlW24gKiAyXSAvKi5Db2RlKi8gPSBiaV9yZXZlcnNlKG5leHRfY29kZVtsZW5dKyssIGxlbik7CgogICAgICAvL1RyYWNlY3YodHJlZSAhPSBzdGF0aWNfbHRyZWUsIChzdGRlcnIsIlxubiAlM2QgJWMgbCAlMmQgYyAlNHggKCV4KSAiLAogICAgICAvLyAgICAgbiwgKGlzZ3JhcGgobikgPyBuIDogJyAnKSwgbGVuLCB0cmVlW25dLkNvZGUsIG5leHRfY29kZVtsZW5dLTEpKTsKICAgIH0KICB9OwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBJbml0aWFsaXplIHRoZSB2YXJpb3VzICdjb25zdGFudCcgdGFibGVzLgogICAqLwogIHZhciB0cl9zdGF0aWNfaW5pdCA9IGZ1bmN0aW9uIHRyX3N0YXRpY19pbml0KCkgewogICAgdmFyIG47IC8qIGl0ZXJhdGVzIG92ZXIgdHJlZSBlbGVtZW50cyAqLwogICAgdmFyIGJpdHM7IC8qIGJpdCBjb3VudGVyICovCiAgICB2YXIgbGVuZ3RoOyAvKiBsZW5ndGggdmFsdWUgKi8KICAgIHZhciBjb2RlOyAvKiBjb2RlIHZhbHVlICovCiAgICB2YXIgZGlzdDsgLyogZGlzdGFuY2UgaW5kZXggKi8KICAgIHZhciBibF9jb3VudCA9IG5ldyBBcnJheShNQVhfQklUUyQxICsgMSk7CiAgICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoIGZvciBhbiBvcHRpbWFsIHRyZWUgKi8KCiAgICAvLyBkbyBjaGVjayBpbiBfdHJfaW5pdCgpCiAgICAvL2lmIChzdGF0aWNfaW5pdF9kb25lKSByZXR1cm47CgogICAgLyogRm9yIHNvbWUgZW1iZWRkZWQgdGFyZ2V0cywgZ2xvYmFsIHZhcmlhYmxlcyBhcmUgbm90IGluaXRpYWxpemVkOiAqLwogICAgLyojaWZkZWYgTk9fSU5JVF9HTE9CQUxfUE9JTlRFUlMKICAgICAgc3RhdGljX2xfZGVzYy5zdGF0aWNfdHJlZSA9IHN0YXRpY19sdHJlZTsKICAgICAgc3RhdGljX2xfZGVzYy5leHRyYV9iaXRzID0gZXh0cmFfbGJpdHM7CiAgICAgIHN0YXRpY19kX2Rlc2Muc3RhdGljX3RyZWUgPSBzdGF0aWNfZHRyZWU7CiAgICAgIHN0YXRpY19kX2Rlc2MuZXh0cmFfYml0cyA9IGV4dHJhX2RiaXRzOwogICAgICBzdGF0aWNfYmxfZGVzYy5leHRyYV9iaXRzID0gZXh0cmFfYmxiaXRzOwogICAgI2VuZGlmKi8KCiAgICAvKiBJbml0aWFsaXplIHRoZSBtYXBwaW5nIGxlbmd0aCAoMC4uMjU1KSAtPiBsZW5ndGggY29kZSAoMC4uMjgpICovCiAgICBsZW5ndGggPSAwOwogICAgZm9yIChjb2RlID0gMDsgY29kZSA8IExFTkdUSF9DT0RFUyQxIC0gMTsgY29kZSsrKSB7CiAgICAgIGJhc2VfbGVuZ3RoW2NvZGVdID0gbGVuZ3RoOwogICAgICBmb3IgKG4gPSAwOyBuIDwgMSA8PCBleHRyYV9sYml0c1tjb2RlXTsgbisrKSB7CiAgICAgICAgX2xlbmd0aF9jb2RlW2xlbmd0aCsrXSA9IGNvZGU7CiAgICAgIH0KICAgIH0KICAgIC8vQXNzZXJ0IChsZW5ndGggPT0gMjU2LCAidHJfc3RhdGljX2luaXQ6IGxlbmd0aCAhPSAyNTYiKTsKICAgIC8qIE5vdGUgdGhhdCB0aGUgbGVuZ3RoIDI1NSAobWF0Y2ggbGVuZ3RoIDI1OCkgY2FuIGJlIHJlcHJlc2VudGVkCiAgICAgKiBpbiB0d28gZGlmZmVyZW50IHdheXM6IGNvZGUgMjg0ICsgNSBiaXRzIG9yIGNvZGUgMjg1LCBzbyB3ZQogICAgICogb3ZlcndyaXRlIGxlbmd0aF9jb2RlWzI1NV0gdG8gdXNlIHRoZSBiZXN0IGVuY29kaW5nOgogICAgICovCiAgICBfbGVuZ3RoX2NvZGVbbGVuZ3RoIC0gMV0gPSBjb2RlOwoKICAgIC8qIEluaXRpYWxpemUgdGhlIG1hcHBpbmcgZGlzdCAoMC4uMzJLKSAtPiBkaXN0IGNvZGUgKDAuLjI5KSAqLwogICAgZGlzdCA9IDA7CiAgICBmb3IgKGNvZGUgPSAwOyBjb2RlIDwgMTY7IGNvZGUrKykgewogICAgICBiYXNlX2Rpc3RbY29kZV0gPSBkaXN0OwogICAgICBmb3IgKG4gPSAwOyBuIDwgMSA8PCBleHRyYV9kYml0c1tjb2RlXTsgbisrKSB7CiAgICAgICAgX2Rpc3RfY29kZVtkaXN0KytdID0gY29kZTsKICAgICAgfQogICAgfQogICAgLy9Bc3NlcnQgKGRpc3QgPT0gMjU2LCAidHJfc3RhdGljX2luaXQ6IGRpc3QgIT0gMjU2Iik7CiAgICBkaXN0ID4+PSA3OyAvKiBmcm9tIG5vdyBvbiwgYWxsIGRpc3RhbmNlcyBhcmUgZGl2aWRlZCBieSAxMjggKi8KICAgIGZvciAoOyBjb2RlIDwgRF9DT0RFUyQxOyBjb2RlKyspIHsKICAgICAgYmFzZV9kaXN0W2NvZGVdID0gZGlzdCA8PCA3OwogICAgICBmb3IgKG4gPSAwOyBuIDwgMSA8PCBleHRyYV9kYml0c1tjb2RlXSAtIDc7IG4rKykgewogICAgICAgIF9kaXN0X2NvZGVbMjU2ICsgZGlzdCsrXSA9IGNvZGU7CiAgICAgIH0KICAgIH0KICAgIC8vQXNzZXJ0IChkaXN0ID09IDI1NiwgInRyX3N0YXRpY19pbml0OiAyNTYrZGlzdCAhPSA1MTIiKTsKCiAgICAvKiBDb25zdHJ1Y3QgdGhlIGNvZGVzIG9mIHRoZSBzdGF0aWMgbGl0ZXJhbCB0cmVlICovCiAgICBmb3IgKGJpdHMgPSAwOyBiaXRzIDw9IE1BWF9CSVRTJDE7IGJpdHMrKykgewogICAgICBibF9jb3VudFtiaXRzXSA9IDA7CiAgICB9CiAgICBuID0gMDsKICAgIHdoaWxlIChuIDw9IDE0MykgewogICAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXSAvKi5MZW4qLyA9IDg7CiAgICAgIG4rKzsKICAgICAgYmxfY291bnRbOF0rKzsKICAgIH0KICAgIHdoaWxlIChuIDw9IDI1NSkgewogICAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXSAvKi5MZW4qLyA9IDk7CiAgICAgIG4rKzsKICAgICAgYmxfY291bnRbOV0rKzsKICAgIH0KICAgIHdoaWxlIChuIDw9IDI3OSkgewogICAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXSAvKi5MZW4qLyA9IDc7CiAgICAgIG4rKzsKICAgICAgYmxfY291bnRbN10rKzsKICAgIH0KICAgIHdoaWxlIChuIDw9IDI4NykgewogICAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXSAvKi5MZW4qLyA9IDg7CiAgICAgIG4rKzsKICAgICAgYmxfY291bnRbOF0rKzsKICAgIH0KICAgIC8qIENvZGVzIDI4NiBhbmQgMjg3IGRvIG5vdCBleGlzdCwgYnV0IHdlIG11c3QgaW5jbHVkZSB0aGVtIGluIHRoZQogICAgICogdHJlZSBjb25zdHJ1Y3Rpb24gdG8gZ2V0IGEgY2Fub25pY2FsIEh1ZmZtYW4gdHJlZSAobG9uZ2VzdCBjb2RlCiAgICAgKiBhbGwgb25lcykKICAgICAqLwogICAgZ2VuX2NvZGVzKHN0YXRpY19sdHJlZSwgTF9DT0RFUyQxICsgMSwgYmxfY291bnQpOwoKICAgIC8qIFRoZSBzdGF0aWMgZGlzdGFuY2UgdHJlZSBpcyB0cml2aWFsOiAqLwogICAgZm9yIChuID0gMDsgbiA8IERfQ09ERVMkMTsgbisrKSB7CiAgICAgIHN0YXRpY19kdHJlZVtuICogMiArIDFdIC8qLkxlbiovID0gNTsKICAgICAgc3RhdGljX2R0cmVlW24gKiAyXSAvKi5Db2RlKi8gPSBiaV9yZXZlcnNlKG4sIDUpOwogICAgfQoKICAgIC8vIE5vdyBkYXRhIHJlYWR5IGFuZCB3ZSBjYW4gaW5pdCBzdGF0aWMgdHJlZXMKICAgIHN0YXRpY19sX2Rlc2MgPSBuZXcgU3RhdGljVHJlZURlc2Moc3RhdGljX2x0cmVlLCBleHRyYV9sYml0cywgTElURVJBTFMkMSArIDEsIExfQ09ERVMkMSwgTUFYX0JJVFMkMSk7CiAgICBzdGF0aWNfZF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKHN0YXRpY19kdHJlZSwgZXh0cmFfZGJpdHMsIDAsIERfQ09ERVMkMSwgTUFYX0JJVFMkMSk7CiAgICBzdGF0aWNfYmxfZGVzYyA9IG5ldyBTdGF0aWNUcmVlRGVzYyhuZXcgQXJyYXkoMCksIGV4dHJhX2JsYml0cywgMCwgQkxfQ09ERVMkMSwgTUFYX0JMX0JJVFMpOwoKICAgIC8vc3RhdGljX2luaXRfZG9uZSA9IHRydWU7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogSW5pdGlhbGl6ZSBhIG5ldyBibG9jay4KICAgKi8KICB2YXIgaW5pdF9ibG9jayA9IGZ1bmN0aW9uIGluaXRfYmxvY2socykgewogICAgdmFyIG47IC8qIGl0ZXJhdGVzIG92ZXIgdHJlZSBlbGVtZW50cyAqLwoKICAgIC8qIEluaXRpYWxpemUgdGhlIHRyZWVzLiAqLwogICAgZm9yIChuID0gMDsgbiA8IExfQ09ERVMkMTsgbisrKSB7CiAgICAgIHMuZHluX2x0cmVlW24gKiAyXSAvKi5GcmVxKi8gPSAwOwogICAgfQogICAgZm9yIChuID0gMDsgbiA8IERfQ09ERVMkMTsgbisrKSB7CiAgICAgIHMuZHluX2R0cmVlW24gKiAyXSAvKi5GcmVxKi8gPSAwOwogICAgfQogICAgZm9yIChuID0gMDsgbiA8IEJMX0NPREVTJDE7IG4rKykgewogICAgICBzLmJsX3RyZWVbbiAqIDJdIC8qLkZyZXEqLyA9IDA7CiAgICB9CiAgICBzLmR5bl9sdHJlZVtFTkRfQkxPQ0sgKiAyXSAvKi5GcmVxKi8gPSAxOwogICAgcy5vcHRfbGVuID0gcy5zdGF0aWNfbGVuID0gMDsKICAgIHMubGFzdF9saXQgPSBzLm1hdGNoZXMgPSAwOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIEZsdXNoIHRoZSBiaXQgYnVmZmVyIGFuZCBhbGlnbiB0aGUgb3V0cHV0IG9uIGEgYnl0ZSBib3VuZGFyeQogICAqLwogIHZhciBiaV93aW5kdXAgPSBmdW5jdGlvbiBiaV93aW5kdXAocykgewogICAgaWYgKHMuYmlfdmFsaWQgPiA4KSB7CiAgICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7CiAgICB9IGVsc2UgaWYgKHMuYmlfdmFsaWQgPiAwKSB7CiAgICAgIC8vcHV0X2J5dGUocywgKEJ5dGUpcy0+YmlfYnVmKTsKICAgICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBzLmJpX2J1ZjsKICAgIH0KICAgIHMuYmlfYnVmID0gMDsKICAgIHMuYmlfdmFsaWQgPSAwOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIENvcHkgYSBzdG9yZWQgYmxvY2ssIHN0b3JpbmcgZmlyc3QgdGhlIGxlbmd0aCBhbmQgaXRzCiAgICogb25lJ3MgY29tcGxlbWVudCBpZiByZXF1ZXN0ZWQuCiAgICovCiAgdmFyIGNvcHlfYmxvY2sgPSBmdW5jdGlvbiBjb3B5X2Jsb2NrKHMsIGJ1ZiwgbGVuLCBoZWFkZXIpCiAgLy9EZWZsYXRlU3RhdGUgKnM7CiAgLy9jaGFyZiAgICAqYnVmOyAgICAvKiB0aGUgaW5wdXQgZGF0YSAqLwogIC8vdW5zaWduZWQgbGVuOyAgICAgLyogaXRzIGxlbmd0aCAqLwogIC8vaW50ICAgICAgaGVhZGVyOyAgLyogdHJ1ZSBpZiBibG9jayBoZWFkZXIgbXVzdCBiZSB3cml0dGVuICovCiAgewogICAgYmlfd2luZHVwKHMpOyAvKiBhbGlnbiBvbiBieXRlIGJvdW5kYXJ5ICovCgogICAgaWYgKGhlYWRlcikgewogICAgICBwdXRfc2hvcnQocywgbGVuKTsKICAgICAgcHV0X3Nob3J0KHMsIH5sZW4pOwogICAgfQogICAgLy8gIHdoaWxlIChsZW4tLSkgewogICAgLy8gICAgcHV0X2J5dGUocywgKmJ1ZisrKTsKICAgIC8vICB9CiAgICBzLnBlbmRpbmdfYnVmLnNldChzLndpbmRvdy5zdWJhcnJheShidWYsIGJ1ZiArIGxlbiksIHMucGVuZGluZyk7CiAgICBzLnBlbmRpbmcgKz0gbGVuOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIENvbXBhcmVzIHRvIHN1YnRyZWVzLCB1c2luZyB0aGUgdHJlZSBkZXB0aCBhcyB0aWUgYnJlYWtlciB3aGVuCiAgICogdGhlIHN1YnRyZWVzIGhhdmUgZXF1YWwgZnJlcXVlbmN5LiBUaGlzIG1pbmltaXplcyB0aGUgd29yc3QgY2FzZSBsZW5ndGguCiAgICovCiAgdmFyIHNtYWxsZXIgPSBmdW5jdGlvbiBzbWFsbGVyKHRyZWUsIG4sIG0sIGRlcHRoKSB7CiAgICB2YXIgX24yID0gbiAqIDI7CiAgICB2YXIgX20yID0gbSAqIDI7CiAgICByZXR1cm4gdHJlZVtfbjJdIC8qLkZyZXEqLyA8IHRyZWVbX20yXSAvKi5GcmVxKi8gfHwgdHJlZVtfbjJdIC8qLkZyZXEqLyA9PT0gdHJlZVtfbTJdIC8qLkZyZXEqLyAmJiBkZXB0aFtuXSA8PSBkZXB0aFttXTsKICB9OwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBSZXN0b3JlIHRoZSBoZWFwIHByb3BlcnR5IGJ5IG1vdmluZyBkb3duIHRoZSB0cmVlIHN0YXJ0aW5nIGF0IG5vZGUgaywKICAgKiBleGNoYW5naW5nIGEgbm9kZSB3aXRoIHRoZSBzbWFsbGVzdCBvZiBpdHMgdHdvIHNvbnMgaWYgbmVjZXNzYXJ5LCBzdG9wcGluZwogICAqIHdoZW4gdGhlIGhlYXAgcHJvcGVydHkgaXMgcmUtZXN0YWJsaXNoZWQgKGVhY2ggZmF0aGVyIHNtYWxsZXIgdGhhbiBpdHMKICAgKiB0d28gc29ucykuCiAgICovCiAgdmFyIHBxZG93bmhlYXAgPSBmdW5jdGlvbiBwcWRvd25oZWFwKHMsIHRyZWUsIGspCiAgLy8gICAgZGVmbGF0ZV9zdGF0ZSAqczsKICAvLyAgICBjdF9kYXRhICp0cmVlOyAgLyogdGhlIHRyZWUgdG8gcmVzdG9yZSAqLwogIC8vICAgIGludCBrOyAgICAgICAgICAgICAgIC8qIG5vZGUgdG8gbW92ZSBkb3duICovCiAgewogICAgdmFyIHYgPSBzLmhlYXBba107CiAgICB2YXIgaiA9IGsgPDwgMTsgLyogbGVmdCBzb24gb2YgayAqLwogICAgd2hpbGUgKGogPD0gcy5oZWFwX2xlbikgewogICAgICAvKiBTZXQgaiB0byB0aGUgc21hbGxlc3Qgb2YgdGhlIHR3byBzb25zOiAqLwogICAgICBpZiAoaiA8IHMuaGVhcF9sZW4gJiYgc21hbGxlcih0cmVlLCBzLmhlYXBbaiArIDFdLCBzLmhlYXBbal0sIHMuZGVwdGgpKSB7CiAgICAgICAgaisrOwogICAgICB9CiAgICAgIC8qIEV4aXQgaWYgdiBpcyBzbWFsbGVyIHRoYW4gYm90aCBzb25zICovCiAgICAgIGlmIChzbWFsbGVyKHRyZWUsIHYsIHMuaGVhcFtqXSwgcy5kZXB0aCkpIHsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgLyogRXhjaGFuZ2UgdiB3aXRoIHRoZSBzbWFsbGVzdCBzb24gKi8KICAgICAgcy5oZWFwW2tdID0gcy5oZWFwW2pdOwogICAgICBrID0gajsKCiAgICAgIC8qIEFuZCBjb250aW51ZSBkb3duIHRoZSB0cmVlLCBzZXR0aW5nIGogdG8gdGhlIGxlZnQgc29uIG9mIGsgKi8KICAgICAgaiA8PD0gMTsKICAgIH0KICAgIHMuaGVhcFtrXSA9IHY7CiAgfTsKCiAgLy8gaW5saW5lZCBtYW51YWxseQogIC8vIGNvbnN0IFNNQUxMRVNUID0gMTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogU2VuZCB0aGUgYmxvY2sgZGF0YSBjb21wcmVzc2VkIHVzaW5nIHRoZSBnaXZlbiBIdWZmbWFuIHRyZWVzCiAgICovCiAgdmFyIGNvbXByZXNzX2Jsb2NrID0gZnVuY3Rpb24gY29tcHJlc3NfYmxvY2socywgbHRyZWUsIGR0cmVlKQogIC8vICAgIGRlZmxhdGVfc3RhdGUgKnM7CiAgLy8gICAgY29uc3QgY3RfZGF0YSAqbHRyZWU7IC8qIGxpdGVyYWwgdHJlZSAqLwogIC8vICAgIGNvbnN0IGN0X2RhdGEgKmR0cmVlOyAvKiBkaXN0YW5jZSB0cmVlICovCiAgewogICAgdmFyIGRpc3Q7IC8qIGRpc3RhbmNlIG9mIG1hdGNoZWQgc3RyaW5nICovCiAgICB2YXIgbGM7IC8qIG1hdGNoIGxlbmd0aCBvciB1bm1hdGNoZWQgY2hhciAoaWYgZGlzdCA9PSAwKSAqLwogICAgdmFyIGx4ID0gMDsgLyogcnVubmluZyBpbmRleCBpbiBsX2J1ZiAqLwogICAgdmFyIGNvZGU7IC8qIHRoZSBjb2RlIHRvIHNlbmQgKi8KICAgIHZhciBleHRyYTsgLyogbnVtYmVyIG9mIGV4dHJhIGJpdHMgdG8gc2VuZCAqLwoKICAgIGlmIChzLmxhc3RfbGl0ICE9PSAwKSB7CiAgICAgIGRvIHsKICAgICAgICBkaXN0ID0gcy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgbHggKiAyXSA8PCA4IHwgcy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgbHggKiAyICsgMV07CiAgICAgICAgbGMgPSBzLnBlbmRpbmdfYnVmW3MubF9idWYgKyBseF07CiAgICAgICAgbHgrKzsKICAgICAgICBpZiAoZGlzdCA9PT0gMCkgewogICAgICAgICAgc2VuZF9jb2RlKHMsIGxjLCBsdHJlZSk7IC8qIHNlbmQgYSBsaXRlcmFsIGJ5dGUgKi8KICAgICAgICAgIC8vVHJhY2Vjdihpc2dyYXBoKGxjKSwgKHN0ZGVyciwiICclYycgIiwgbGMpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogSGVyZSwgbGMgaXMgdGhlIG1hdGNoIGxlbmd0aCAtIE1JTl9NQVRDSCAqLwogICAgICAgICAgY29kZSA9IF9sZW5ndGhfY29kZVtsY107CiAgICAgICAgICBzZW5kX2NvZGUocywgY29kZSArIExJVEVSQUxTJDEgKyAxLCBsdHJlZSk7IC8qIHNlbmQgdGhlIGxlbmd0aCBjb2RlICovCiAgICAgICAgICBleHRyYSA9IGV4dHJhX2xiaXRzW2NvZGVdOwogICAgICAgICAgaWYgKGV4dHJhICE9PSAwKSB7CiAgICAgICAgICAgIGxjIC09IGJhc2VfbGVuZ3RoW2NvZGVdOwogICAgICAgICAgICBzZW5kX2JpdHMocywgbGMsIGV4dHJhKTsgLyogc2VuZCB0aGUgZXh0cmEgbGVuZ3RoIGJpdHMgKi8KICAgICAgICAgIH0KICAgICAgICAgIGRpc3QtLTsgLyogZGlzdCBpcyBub3cgdGhlIG1hdGNoIGRpc3RhbmNlIC0gMSAqLwogICAgICAgICAgY29kZSA9IGRfY29kZShkaXN0KTsKICAgICAgICAgIC8vQXNzZXJ0IChjb2RlIDwgRF9DT0RFUywgImJhZCBkX2NvZGUiKTsKCiAgICAgICAgICBzZW5kX2NvZGUocywgY29kZSwgZHRyZWUpOyAvKiBzZW5kIHRoZSBkaXN0YW5jZSBjb2RlICovCiAgICAgICAgICBleHRyYSA9IGV4dHJhX2RiaXRzW2NvZGVdOwogICAgICAgICAgaWYgKGV4dHJhICE9PSAwKSB7CiAgICAgICAgICAgIGRpc3QgLT0gYmFzZV9kaXN0W2NvZGVdOwogICAgICAgICAgICBzZW5kX2JpdHMocywgZGlzdCwgZXh0cmEpOyAvKiBzZW5kIHRoZSBleHRyYSBkaXN0YW5jZSBiaXRzICovCiAgICAgICAgICB9CiAgICAgICAgfSAvKiBsaXRlcmFsIG9yIG1hdGNoIHBhaXIgPyAqLwoKICAgICAgICAvKiBDaGVjayB0aGF0IHRoZSBvdmVybGF5IGJldHdlZW4gcGVuZGluZ19idWYgYW5kIGRfYnVmK2xfYnVmIGlzIG9rOiAqLwogICAgICAgIC8vQXNzZXJ0KCh1SW50KShzLT5wZW5kaW5nKSA8IHMtPmxpdF9idWZzaXplICsgMipseCwKICAgICAgICAvLyAgICAgICAicGVuZGluZ0J1ZiBvdmVyZmxvdyIpOwogICAgICB9IHdoaWxlIChseCA8IHMubGFzdF9saXQpOwogICAgfQogICAgc2VuZF9jb2RlKHMsIEVORF9CTE9DSywgbHRyZWUpOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIENvbnN0cnVjdCBvbmUgSHVmZm1hbiB0cmVlIGFuZCBhc3NpZ25zIHRoZSBjb2RlIGJpdCBzdHJpbmdzIGFuZCBsZW5ndGhzLgogICAqIFVwZGF0ZSB0aGUgdG90YWwgYml0IGxlbmd0aCBmb3IgdGhlIGN1cnJlbnQgYmxvY2suCiAgICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGQgZnJlcSBpcyBzZXQgZm9yIGFsbCB0cmVlIGVsZW1lbnRzLgogICAqIE9VVCBhc3NlcnRpb25zOiB0aGUgZmllbGRzIGxlbiBhbmQgY29kZSBhcmUgc2V0IHRvIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGgKICAgKiAgICAgYW5kIGNvcnJlc3BvbmRpbmcgY29kZS4gVGhlIGxlbmd0aCBvcHRfbGVuIGlzIHVwZGF0ZWQ7IHN0YXRpY19sZW4gaXMKICAgKiAgICAgYWxzbyB1cGRhdGVkIGlmIHN0cmVlIGlzIG5vdCBudWxsLiBUaGUgZmllbGQgbWF4X2NvZGUgaXMgc2V0LgogICAqLwogIHZhciBidWlsZF90cmVlID0gZnVuY3Rpb24gYnVpbGRfdHJlZShzLCBkZXNjKQogIC8vICAgIGRlZmxhdGVfc3RhdGUgKnM7CiAgLy8gICAgdHJlZV9kZXNjICpkZXNjOyAvKiB0aGUgdHJlZSBkZXNjcmlwdG9yICovCiAgewogICAgdmFyIHRyZWUgPSBkZXNjLmR5bl90cmVlOwogICAgdmFyIHN0cmVlID0gZGVzYy5zdGF0X2Rlc2Muc3RhdGljX3RyZWU7CiAgICB2YXIgaGFzX3N0cmVlID0gZGVzYy5zdGF0X2Rlc2MuaGFzX3N0cmVlOwogICAgdmFyIGVsZW1zID0gZGVzYy5zdGF0X2Rlc2MuZWxlbXM7CiAgICB2YXIgbiwgbTsgLyogaXRlcmF0ZSBvdmVyIGhlYXAgZWxlbWVudHMgKi8KICAgIHZhciBtYXhfY29kZSA9IC0xOyAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi8KICAgIHZhciBub2RlOyAvKiBuZXcgbm9kZSBiZWluZyBjcmVhdGVkICovCgogICAgLyogQ29uc3RydWN0IHRoZSBpbml0aWFsIGhlYXAsIHdpdGggbGVhc3QgZnJlcXVlbnQgZWxlbWVudCBpbgogICAgICogaGVhcFtTTUFMTEVTVF0uIFRoZSBzb25zIG9mIGhlYXBbbl0gYXJlIGhlYXBbMipuXSBhbmQgaGVhcFsyKm4rMV0uCiAgICAgKiBoZWFwWzBdIGlzIG5vdCB1c2VkLgogICAgICovCiAgICBzLmhlYXBfbGVuID0gMDsKICAgIHMuaGVhcF9tYXggPSBIRUFQX1NJWkUkMTsKICAgIGZvciAobiA9IDA7IG4gPCBlbGVtczsgbisrKSB7CiAgICAgIGlmICh0cmVlW24gKiAyXSAvKi5GcmVxKi8gIT09IDApIHsKICAgICAgICBzLmhlYXBbKytzLmhlYXBfbGVuXSA9IG1heF9jb2RlID0gbjsKICAgICAgICBzLmRlcHRoW25dID0gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICB0cmVlW24gKiAyICsgMV0gLyouTGVuKi8gPSAwOwogICAgICB9CiAgICB9CgogICAgLyogVGhlIHBremlwIGZvcm1hdCByZXF1aXJlcyB0aGF0IGF0IGxlYXN0IG9uZSBkaXN0YW5jZSBjb2RlIGV4aXN0cywKICAgICAqIGFuZCB0aGF0IGF0IGxlYXN0IG9uZSBiaXQgc2hvdWxkIGJlIHNlbnQgZXZlbiBpZiB0aGVyZSBpcyBvbmx5IG9uZQogICAgICogcG9zc2libGUgY29kZS4gU28gdG8gYXZvaWQgc3BlY2lhbCBjaGVja3MgbGF0ZXIgb24gd2UgZm9yY2UgYXQgbGVhc3QKICAgICAqIHR3byBjb2RlcyBvZiBub24gemVybyBmcmVxdWVuY3kuCiAgICAgKi8KICAgIHdoaWxlIChzLmhlYXBfbGVuIDwgMikgewogICAgICBub2RlID0gcy5oZWFwWysrcy5oZWFwX2xlbl0gPSBtYXhfY29kZSA8IDIgPyArK21heF9jb2RlIDogMDsKICAgICAgdHJlZVtub2RlICogMl0gLyouRnJlcSovID0gMTsKICAgICAgcy5kZXB0aFtub2RlXSA9IDA7CiAgICAgIHMub3B0X2xlbi0tOwogICAgICBpZiAoaGFzX3N0cmVlKSB7CiAgICAgICAgcy5zdGF0aWNfbGVuIC09IHN0cmVlW25vZGUgKiAyICsgMV0gLyouTGVuKi87CiAgICAgIH0KICAgICAgLyogbm9kZSBpcyAwIG9yIDEgc28gaXQgZG9lcyBub3QgaGF2ZSBleHRyYSBiaXRzICovCiAgICB9CiAgICBkZXNjLm1heF9jb2RlID0gbWF4X2NvZGU7CgogICAgLyogVGhlIGVsZW1lbnRzIGhlYXBbaGVhcF9sZW4vMisxIC4uIGhlYXBfbGVuXSBhcmUgbGVhdmVzIG9mIHRoZSB0cmVlLAogICAgICogZXN0YWJsaXNoIHN1Yi1oZWFwcyBvZiBpbmNyZWFzaW5nIGxlbmd0aHM6CiAgICAgKi8KICAgIGZvciAobiA9IHMuaGVhcF9sZW4gPj4gMSAvKmludCAvMiovOyBuID49IDE7IG4tLSkgewogICAgICBwcWRvd25oZWFwKHMsIHRyZWUsIG4pOwogICAgfQoKICAgIC8qIENvbnN0cnVjdCB0aGUgSHVmZm1hbiB0cmVlIGJ5IHJlcGVhdGVkbHkgY29tYmluaW5nIHRoZSBsZWFzdCB0d28KICAgICAqIGZyZXF1ZW50IG5vZGVzLgogICAgICovCiAgICBub2RlID0gZWxlbXM7IC8qIG5leHQgaW50ZXJuYWwgbm9kZSBvZiB0aGUgdHJlZSAqLwogICAgZG8gewogICAgICAvL3BxcmVtb3ZlKHMsIHRyZWUsIG4pOyAgLyogbiA9IG5vZGUgb2YgbGVhc3QgZnJlcXVlbmN5ICovCiAgICAgIC8qKiogcHFyZW1vdmUgKioqLwogICAgICBuID0gcy5oZWFwWzEgLypTTUFMTEVTVCovXTsKICAgICAgcy5oZWFwWzEgLypTTUFMTEVTVCovXSA9IHMuaGVhcFtzLmhlYXBfbGVuLS1dOwogICAgICBwcWRvd25oZWFwKHMsIHRyZWUsIDEgLypTTUFMTEVTVCovKTsKICAgICAgLyoqKi8KCiAgICAgIG0gPSBzLmhlYXBbMSAvKlNNQUxMRVNUKi9dOyAvKiBtID0gbm9kZSBvZiBuZXh0IGxlYXN0IGZyZXF1ZW5jeSAqLwoKICAgICAgcy5oZWFwWy0tcy5oZWFwX21heF0gPSBuOyAvKiBrZWVwIHRoZSBub2RlcyBzb3J0ZWQgYnkgZnJlcXVlbmN5ICovCiAgICAgIHMuaGVhcFstLXMuaGVhcF9tYXhdID0gbTsKCiAgICAgIC8qIENyZWF0ZSBhIG5ldyBub2RlIGZhdGhlciBvZiBuIGFuZCBtICovCiAgICAgIHRyZWVbbm9kZSAqIDJdIC8qLkZyZXEqLyA9IHRyZWVbbiAqIDJdIC8qLkZyZXEqLyArIHRyZWVbbSAqIDJdIC8qLkZyZXEqLzsKICAgICAgcy5kZXB0aFtub2RlXSA9IChzLmRlcHRoW25dID49IHMuZGVwdGhbbV0gPyBzLmRlcHRoW25dIDogcy5kZXB0aFttXSkgKyAxOwogICAgICB0cmVlW24gKiAyICsgMV0gLyouRGFkKi8gPSB0cmVlW20gKiAyICsgMV0gLyouRGFkKi8gPSBub2RlOwoKICAgICAgLyogYW5kIGluc2VydCB0aGUgbmV3IG5vZGUgaW4gdGhlIGhlYXAgKi8KICAgICAgcy5oZWFwWzEgLypTTUFMTEVTVCovXSA9IG5vZGUrKzsKICAgICAgcHFkb3duaGVhcChzLCB0cmVlLCAxIC8qU01BTExFU1QqLyk7CiAgICB9IHdoaWxlIChzLmhlYXBfbGVuID49IDIpOwogICAgcy5oZWFwWy0tcy5oZWFwX21heF0gPSBzLmhlYXBbMSAvKlNNQUxMRVNUKi9dOwoKICAgIC8qIEF0IHRoaXMgcG9pbnQsIHRoZSBmaWVsZHMgZnJlcSBhbmQgZGFkIGFyZSBzZXQuIFdlIGNhbiBub3cKICAgICAqIGdlbmVyYXRlIHRoZSBiaXQgbGVuZ3Rocy4KICAgICAqLwogICAgZ2VuX2JpdGxlbihzLCBkZXNjKTsKCiAgICAvKiBUaGUgZmllbGQgbGVuIGlzIG5vdyBzZXQsIHdlIGNhbiBnZW5lcmF0ZSB0aGUgYml0IGNvZGVzICovCiAgICBnZW5fY29kZXModHJlZSwgbWF4X2NvZGUsIHMuYmxfY291bnQpOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFNjYW4gYSBsaXRlcmFsIG9yIGRpc3RhbmNlIHRyZWUgdG8gZGV0ZXJtaW5lIHRoZSBmcmVxdWVuY2llcyBvZiB0aGUgY29kZXMKICAgKiBpbiB0aGUgYml0IGxlbmd0aCB0cmVlLgogICAqLwogIHZhciBzY2FuX3RyZWUgPSBmdW5jdGlvbiBzY2FuX3RyZWUocywgdHJlZSwgbWF4X2NvZGUpCiAgLy8gICAgZGVmbGF0ZV9zdGF0ZSAqczsKICAvLyAgICBjdF9kYXRhICp0cmVlOyAgIC8qIHRoZSB0cmVlIHRvIGJlIHNjYW5uZWQgKi8KICAvLyAgICBpbnQgbWF4X2NvZGU7ICAgIC8qIGFuZCBpdHMgbGFyZ2VzdCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXF1ZW5jeSAqLwogIHsKICAgIHZhciBuOyAvKiBpdGVyYXRlcyBvdmVyIGFsbCB0cmVlIGVsZW1lbnRzICovCiAgICB2YXIgcHJldmxlbiA9IC0xOyAvKiBsYXN0IGVtaXR0ZWQgbGVuZ3RoICovCiAgICB2YXIgY3VybGVuOyAvKiBsZW5ndGggb2YgY3VycmVudCBjb2RlICovCgogICAgdmFyIG5leHRsZW4gPSB0cmVlWzAgKiAyICsgMV0gLyouTGVuKi87IC8qIGxlbmd0aCBvZiBuZXh0IGNvZGUgKi8KCiAgICB2YXIgY291bnQgPSAwOyAvKiByZXBlYXQgY291bnQgb2YgdGhlIGN1cnJlbnQgY29kZSAqLwogICAgdmFyIG1heF9jb3VudCA9IDc7IC8qIG1heCByZXBlYXQgY291bnQgKi8KICAgIHZhciBtaW5fY291bnQgPSA0OyAvKiBtaW4gcmVwZWF0IGNvdW50ICovCgogICAgaWYgKG5leHRsZW4gPT09IDApIHsKICAgICAgbWF4X2NvdW50ID0gMTM4OwogICAgICBtaW5fY291bnQgPSAzOwogICAgfQogICAgdHJlZVsobWF4X2NvZGUgKyAxKSAqIDIgKyAxXSAvKi5MZW4qLyA9IDB4ZmZmZjsgLyogZ3VhcmQgKi8KCiAgICBmb3IgKG4gPSAwOyBuIDw9IG1heF9jb2RlOyBuKyspIHsKICAgICAgY3VybGVuID0gbmV4dGxlbjsKICAgICAgbmV4dGxlbiA9IHRyZWVbKG4gKyAxKSAqIDIgKyAxXSAvKi5MZW4qLzsKICAgICAgaWYgKCsrY291bnQgPCBtYXhfY291bnQgJiYgY3VybGVuID09PSBuZXh0bGVuKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0gZWxzZSBpZiAoY291bnQgPCBtaW5fY291bnQpIHsKICAgICAgICBzLmJsX3RyZWVbY3VybGVuICogMl0gLyouRnJlcSovICs9IGNvdW50OwogICAgICB9IGVsc2UgaWYgKGN1cmxlbiAhPT0gMCkgewogICAgICAgIGlmIChjdXJsZW4gIT09IHByZXZsZW4pIHsKICAgICAgICAgIHMuYmxfdHJlZVtjdXJsZW4gKiAyXSAvKi5GcmVxKi8rKzsKICAgICAgICB9CiAgICAgICAgcy5ibF90cmVlW1JFUF8zXzYgKiAyXSAvKi5GcmVxKi8rKzsKICAgICAgfSBlbHNlIGlmIChjb3VudCA8PSAxMCkgewogICAgICAgIHMuYmxfdHJlZVtSRVBaXzNfMTAgKiAyXSAvKi5GcmVxKi8rKzsKICAgICAgfSBlbHNlIHsKICAgICAgICBzLmJsX3RyZWVbUkVQWl8xMV8xMzggKiAyXSAvKi5GcmVxKi8rKzsKICAgICAgfQogICAgICBjb3VudCA9IDA7CiAgICAgIHByZXZsZW4gPSBjdXJsZW47CiAgICAgIGlmIChuZXh0bGVuID09PSAwKSB7CiAgICAgICAgbWF4X2NvdW50ID0gMTM4OwogICAgICAgIG1pbl9jb3VudCA9IDM7CiAgICAgIH0gZWxzZSBpZiAoY3VybGVuID09PSBuZXh0bGVuKSB7CiAgICAgICAgbWF4X2NvdW50ID0gNjsKICAgICAgICBtaW5fY291bnQgPSAzOwogICAgICB9IGVsc2UgewogICAgICAgIG1heF9jb3VudCA9IDc7CiAgICAgICAgbWluX2NvdW50ID0gNDsKICAgICAgfQogICAgfQogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFNlbmQgYSBsaXRlcmFsIG9yIGRpc3RhbmNlIHRyZWUgaW4gY29tcHJlc3NlZCBmb3JtLCB1c2luZyB0aGUgY29kZXMgaW4KICAgKiBibF90cmVlLgogICAqLwogIHZhciBzZW5kX3RyZWUgPSBmdW5jdGlvbiBzZW5kX3RyZWUocywgdHJlZSwgbWF4X2NvZGUpCiAgLy8gICAgZGVmbGF0ZV9zdGF0ZSAqczsKICAvLyAgICBjdF9kYXRhICp0cmVlOyAvKiB0aGUgdHJlZSB0byBiZSBzY2FubmVkICovCiAgLy8gICAgaW50IG1heF9jb2RlOyAgICAgICAvKiBhbmQgaXRzIGxhcmdlc3QgY29kZSBvZiBub24gemVybyBmcmVxdWVuY3kgKi8KICB7CiAgICB2YXIgbjsgLyogaXRlcmF0ZXMgb3ZlciBhbGwgdHJlZSBlbGVtZW50cyAqLwogICAgdmFyIHByZXZsZW4gPSAtMTsgLyogbGFzdCBlbWl0dGVkIGxlbmd0aCAqLwogICAgdmFyIGN1cmxlbjsgLyogbGVuZ3RoIG9mIGN1cnJlbnQgY29kZSAqLwoKICAgIHZhciBuZXh0bGVuID0gdHJlZVswICogMiArIDFdIC8qLkxlbiovOyAvKiBsZW5ndGggb2YgbmV4dCBjb2RlICovCgogICAgdmFyIGNvdW50ID0gMDsgLyogcmVwZWF0IGNvdW50IG9mIHRoZSBjdXJyZW50IGNvZGUgKi8KICAgIHZhciBtYXhfY291bnQgPSA3OyAvKiBtYXggcmVwZWF0IGNvdW50ICovCiAgICB2YXIgbWluX2NvdW50ID0gNDsgLyogbWluIHJlcGVhdCBjb3VudCAqLwoKICAgIC8qIHRyZWVbbWF4X2NvZGUrMV0uTGVuID0gLTE7ICovIC8qIGd1YXJkIGFscmVhZHkgc2V0ICovCiAgICBpZiAobmV4dGxlbiA9PT0gMCkgewogICAgICBtYXhfY291bnQgPSAxMzg7CiAgICAgIG1pbl9jb3VudCA9IDM7CiAgICB9CiAgICBmb3IgKG4gPSAwOyBuIDw9IG1heF9jb2RlOyBuKyspIHsKICAgICAgY3VybGVuID0gbmV4dGxlbjsKICAgICAgbmV4dGxlbiA9IHRyZWVbKG4gKyAxKSAqIDIgKyAxXSAvKi5MZW4qLzsKICAgICAgaWYgKCsrY291bnQgPCBtYXhfY291bnQgJiYgY3VybGVuID09PSBuZXh0bGVuKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0gZWxzZSBpZiAoY291bnQgPCBtaW5fY291bnQpIHsKICAgICAgICBkbyB7CiAgICAgICAgICBzZW5kX2NvZGUocywgY3VybGVuLCBzLmJsX3RyZWUpOwogICAgICAgIH0gd2hpbGUgKC0tY291bnQgIT09IDApOwogICAgICB9IGVsc2UgaWYgKGN1cmxlbiAhPT0gMCkgewogICAgICAgIGlmIChjdXJsZW4gIT09IHByZXZsZW4pIHsKICAgICAgICAgIHNlbmRfY29kZShzLCBjdXJsZW4sIHMuYmxfdHJlZSk7CiAgICAgICAgICBjb3VudC0tOwogICAgICAgIH0KICAgICAgICAvL0Fzc2VydChjb3VudCA+PSAzICYmIGNvdW50IDw9IDYsICIgM182PyIpOwogICAgICAgIHNlbmRfY29kZShzLCBSRVBfM182LCBzLmJsX3RyZWUpOwogICAgICAgIHNlbmRfYml0cyhzLCBjb3VudCAtIDMsIDIpOwogICAgICB9IGVsc2UgaWYgKGNvdW50IDw9IDEwKSB7CiAgICAgICAgc2VuZF9jb2RlKHMsIFJFUFpfM18xMCwgcy5ibF90cmVlKTsKICAgICAgICBzZW5kX2JpdHMocywgY291bnQgLSAzLCAzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzZW5kX2NvZGUocywgUkVQWl8xMV8xMzgsIHMuYmxfdHJlZSk7CiAgICAgICAgc2VuZF9iaXRzKHMsIGNvdW50IC0gMTEsIDcpOwogICAgICB9CiAgICAgIGNvdW50ID0gMDsKICAgICAgcHJldmxlbiA9IGN1cmxlbjsKICAgICAgaWYgKG5leHRsZW4gPT09IDApIHsKICAgICAgICBtYXhfY291bnQgPSAxMzg7CiAgICAgICAgbWluX2NvdW50ID0gMzsKICAgICAgfSBlbHNlIGlmIChjdXJsZW4gPT09IG5leHRsZW4pIHsKICAgICAgICBtYXhfY291bnQgPSA2OwogICAgICAgIG1pbl9jb3VudCA9IDM7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbWF4X2NvdW50ID0gNzsKICAgICAgICBtaW5fY291bnQgPSA0OwogICAgICB9CiAgICB9CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogQ29uc3RydWN0IHRoZSBIdWZmbWFuIHRyZWUgZm9yIHRoZSBiaXQgbGVuZ3RocyBhbmQgcmV0dXJuIHRoZSBpbmRleCBpbgogICAqIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLgogICAqLwogIHZhciBidWlsZF9ibF90cmVlID0gZnVuY3Rpb24gYnVpbGRfYmxfdHJlZShzKSB7CiAgICB2YXIgbWF4X2JsaW5kZXg7IC8qIGluZGV4IG9mIGxhc3QgYml0IGxlbmd0aCBjb2RlIG9mIG5vbiB6ZXJvIGZyZXEgKi8KCiAgICAvKiBEZXRlcm1pbmUgdGhlIGJpdCBsZW5ndGggZnJlcXVlbmNpZXMgZm9yIGxpdGVyYWwgYW5kIGRpc3RhbmNlIHRyZWVzICovCiAgICBzY2FuX3RyZWUocywgcy5keW5fbHRyZWUsIHMubF9kZXNjLm1heF9jb2RlKTsKICAgIHNjYW5fdHJlZShzLCBzLmR5bl9kdHJlZSwgcy5kX2Rlc2MubWF4X2NvZGUpOwoKICAgIC8qIEJ1aWxkIHRoZSBiaXQgbGVuZ3RoIHRyZWU6ICovCiAgICBidWlsZF90cmVlKHMsIHMuYmxfZGVzYyk7CiAgICAvKiBvcHRfbGVuIG5vdyBpbmNsdWRlcyB0aGUgbGVuZ3RoIG9mIHRoZSB0cmVlIHJlcHJlc2VudGF0aW9ucywgZXhjZXB0CiAgICAgKiB0aGUgbGVuZ3RocyBvZiB0aGUgYml0IGxlbmd0aHMgY29kZXMgYW5kIHRoZSA1KzUrNCBiaXRzIGZvciB0aGUgY291bnRzLgogICAgICovCgogICAgLyogRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgYml0IGxlbmd0aCBjb2RlcyB0byBzZW5kLiBUaGUgcGt6aXAgZm9ybWF0CiAgICAgKiByZXF1aXJlcyB0aGF0IGF0IGxlYXN0IDQgYml0IGxlbmd0aCBjb2RlcyBiZSBzZW50LiAoYXBwbm90ZS50eHQgc2F5cwogICAgICogMyBidXQgdGhlIGFjdHVhbCB2YWx1ZSB1c2VkIGlzIDQuKQogICAgICovCiAgICBmb3IgKG1heF9ibGluZGV4ID0gQkxfQ09ERVMkMSAtIDE7IG1heF9ibGluZGV4ID49IDM7IG1heF9ibGluZGV4LS0pIHsKICAgICAgaWYgKHMuYmxfdHJlZVtibF9vcmRlclttYXhfYmxpbmRleF0gKiAyICsgMV0gLyouTGVuKi8gIT09IDApIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgLyogVXBkYXRlIG9wdF9sZW4gdG8gaW5jbHVkZSB0aGUgYml0IGxlbmd0aCB0cmVlIGFuZCBjb3VudHMgKi8KICAgIHMub3B0X2xlbiArPSAzICogKG1heF9ibGluZGV4ICsgMSkgKyA1ICsgNSArIDQ7CiAgICAvL1RyYWNldigoc3RkZXJyLCAiXG5keW4gdHJlZXM6IGR5biAlbGQsIHN0YXQgJWxkIiwKICAgIC8vICAgICAgICBzLT5vcHRfbGVuLCBzLT5zdGF0aWNfbGVuKSk7CgogICAgcmV0dXJuIG1heF9ibGluZGV4OwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFNlbmQgdGhlIGhlYWRlciBmb3IgYSBibG9jayB1c2luZyBkeW5hbWljIEh1ZmZtYW4gdHJlZXM6IHRoZSBjb3VudHMsIHRoZQogICAqIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGggY29kZXMsIHRoZSBsaXRlcmFsIHRyZWUgYW5kIHRoZSBkaXN0YW5jZSB0cmVlLgogICAqIElOIGFzc2VydGlvbjogbGNvZGVzID49IDI1NywgZGNvZGVzID49IDEsIGJsY29kZXMgPj0gNC4KICAgKi8KICB2YXIgc2VuZF9hbGxfdHJlZXMgPSBmdW5jdGlvbiBzZW5kX2FsbF90cmVlcyhzLCBsY29kZXMsIGRjb2RlcywgYmxjb2RlcykKICAvLyAgICBkZWZsYXRlX3N0YXRlICpzOwogIC8vICAgIGludCBsY29kZXMsIGRjb2RlcywgYmxjb2RlczsgLyogbnVtYmVyIG9mIGNvZGVzIGZvciBlYWNoIHRyZWUgKi8KICB7CiAgICB2YXIgcmFuazsgLyogaW5kZXggaW4gYmxfb3JkZXIgKi8KCiAgICAvL0Fzc2VydCAobGNvZGVzID49IDI1NyAmJiBkY29kZXMgPj0gMSAmJiBibGNvZGVzID49IDQsICJub3QgZW5vdWdoIGNvZGVzIik7CiAgICAvL0Fzc2VydCAobGNvZGVzIDw9IExfQ09ERVMgJiYgZGNvZGVzIDw9IERfQ09ERVMgJiYgYmxjb2RlcyA8PSBCTF9DT0RFUywKICAgIC8vICAgICAgICAidG9vIG1hbnkgY29kZXMiKTsKICAgIC8vVHJhY2V2KChzdGRlcnIsICJcbmJsIGNvdW50czogIikpOwogICAgc2VuZF9iaXRzKHMsIGxjb2RlcyAtIDI1NywgNSk7IC8qIG5vdCArMjU1IGFzIHN0YXRlZCBpbiBhcHBub3RlLnR4dCAqLwogICAgc2VuZF9iaXRzKHMsIGRjb2RlcyAtIDEsIDUpOwogICAgc2VuZF9iaXRzKHMsIGJsY29kZXMgLSA0LCA0KTsgLyogbm90IC0zIGFzIHN0YXRlZCBpbiBhcHBub3RlLnR4dCAqLwogICAgZm9yIChyYW5rID0gMDsgcmFuayA8IGJsY29kZXM7IHJhbmsrKykgewogICAgICAvL1RyYWNldigoc3RkZXJyLCAiXG5ibCBjb2RlICUyZCAiLCBibF9vcmRlcltyYW5rXSkpOwogICAgICBzZW5kX2JpdHMocywgcy5ibF90cmVlW2JsX29yZGVyW3JhbmtdICogMiArIDFdIC8qLkxlbiovLCAzKTsKICAgIH0KICAgIC8vVHJhY2V2KChzdGRlcnIsICJcbmJsIHRyZWU6IHNlbnQgJWxkIiwgcy0+Yml0c19zZW50KSk7CgogICAgc2VuZF90cmVlKHMsIHMuZHluX2x0cmVlLCBsY29kZXMgLSAxKTsgLyogbGl0ZXJhbCB0cmVlICovCiAgICAvL1RyYWNldigoc3RkZXJyLCAiXG5saXQgdHJlZTogc2VudCAlbGQiLCBzLT5iaXRzX3NlbnQpKTsKCiAgICBzZW5kX3RyZWUocywgcy5keW5fZHRyZWUsIGRjb2RlcyAtIDEpOyAvKiBkaXN0YW5jZSB0cmVlICovCiAgICAvL1RyYWNldigoc3RkZXJyLCAiXG5kaXN0IHRyZWU6IHNlbnQgJWxkIiwgcy0+Yml0c19zZW50KSk7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogQ2hlY2sgaWYgdGhlIGRhdGEgdHlwZSBpcyBURVhUIG9yIEJJTkFSWSwgdXNpbmcgdGhlIGZvbGxvd2luZyBhbGdvcml0aG06CiAgICogLSBURVhUIGlmIHRoZSB0d28gY29uZGl0aW9ucyBiZWxvdyBhcmUgc2F0aXNmaWVkOgogICAqICAgIGEpIFRoZXJlIGFyZSBubyBub24tcG9ydGFibGUgY29udHJvbCBjaGFyYWN0ZXJzIGJlbG9uZ2luZyB0byB0aGUKICAgKiAgICAgICAiYmxhY2sgbGlzdCIgKDAuLjYsIDE0Li4yNSwgMjguLjMxKS4KICAgKiAgICBiKSBUaGVyZSBpcyBhdCBsZWFzdCBvbmUgcHJpbnRhYmxlIGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gdGhlCiAgICogICAgICAgIndoaXRlIGxpc3QiICg5IHtUQUJ9LCAxMCB7TEZ9LCAxMyB7Q1J9LCAzMi4uMjU1KS4KICAgKiAtIEJJTkFSWSBvdGhlcndpc2UuCiAgICogLSBUaGUgZm9sbG93aW5nIHBhcnRpYWxseS1wb3J0YWJsZSBjb250cm9sIGNoYXJhY3RlcnMgZm9ybSBhCiAgICogICAiZ3JheSBsaXN0IiB0aGF0IGlzIGlnbm9yZWQgaW4gdGhpcyBkZXRlY3Rpb24gYWxnb3JpdGhtOgogICAqICAgKDcge0JFTH0sIDgge0JTfSwgMTEge1ZUfSwgMTIge0ZGfSwgMjYge1NVQn0sIDI3IHtFU0N9KS4KICAgKiBJTiBhc3NlcnRpb246IHRoZSBmaWVsZHMgRnJlcSBvZiBkeW5fbHRyZWUgYXJlIHNldC4KICAgKi8KICB2YXIgZGV0ZWN0X2RhdGFfdHlwZSA9IGZ1bmN0aW9uIGRldGVjdF9kYXRhX3R5cGUocykgewogICAgLyogYmxhY2tfbWFzayBpcyB0aGUgYml0IG1hc2sgb2YgYmxhY2stbGlzdGVkIGJ5dGVzCiAgICAgKiBzZXQgYml0cyAwLi42LCAxNC4uMjUsIGFuZCAyOC4uMzEKICAgICAqIDB4ZjNmZmMwN2YgPSBiaW5hcnkgMTExMTAwMTExMTExMTExMTExMDAwMDAwMDExMTExMTEKICAgICAqLwogICAgdmFyIGJsYWNrX21hc2sgPSAweGYzZmZjMDdmOwogICAgdmFyIG47CgogICAgLyogQ2hlY2sgZm9yIG5vbi10ZXh0dWFsICgiYmxhY2stbGlzdGVkIikgYnl0ZXMuICovCiAgICBmb3IgKG4gPSAwOyBuIDw9IDMxOyBuKyssIGJsYWNrX21hc2sgPj4+PSAxKSB7CiAgICAgIGlmIChibGFja19tYXNrICYgMSAmJiBzLmR5bl9sdHJlZVtuICogMl0gLyouRnJlcSovICE9PSAwKSB7CiAgICAgICAgcmV0dXJuIFpfQklOQVJZOwogICAgICB9CiAgICB9CgogICAgLyogQ2hlY2sgZm9yIHRleHR1YWwgKCJ3aGl0ZS1saXN0ZWQiKSBieXRlcy4gKi8KICAgIGlmIChzLmR5bl9sdHJlZVs5ICogMl0gLyouRnJlcSovICE9PSAwIHx8IHMuZHluX2x0cmVlWzEwICogMl0gLyouRnJlcSovICE9PSAwIHx8IHMuZHluX2x0cmVlWzEzICogMl0gLyouRnJlcSovICE9PSAwKSB7CiAgICAgIHJldHVybiBaX1RFWFQ7CiAgICB9CiAgICBmb3IgKG4gPSAzMjsgbiA8IExJVEVSQUxTJDE7IG4rKykgewogICAgICBpZiAocy5keW5fbHRyZWVbbiAqIDJdIC8qLkZyZXEqLyAhPT0gMCkgewogICAgICAgIHJldHVybiBaX1RFWFQ7CiAgICAgIH0KICAgIH0KCiAgICAvKiBUaGVyZSBhcmUgbm8gImJsYWNrLWxpc3RlZCIgb3IgIndoaXRlLWxpc3RlZCIgYnl0ZXM6CiAgICAgKiB0aGlzIHN0cmVhbSBlaXRoZXIgaXMgZW1wdHkgb3IgaGFzIHRvbGVyYXRlZCAoImdyYXktbGlzdGVkIikgYnl0ZXMgb25seS4KICAgICAqLwogICAgcmV0dXJuIFpfQklOQVJZOwogIH07CiAgdmFyIHN0YXRpY19pbml0X2RvbmUgPSBmYWxzZTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogSW5pdGlhbGl6ZSB0aGUgdHJlZSBkYXRhIHN0cnVjdHVyZXMgZm9yIGEgbmV3IHpsaWIgc3RyZWFtLgogICAqLwogIHZhciBfdHJfaW5pdCQxID0gZnVuY3Rpb24gX3RyX2luaXQocykgewogICAgaWYgKCFzdGF0aWNfaW5pdF9kb25lKSB7CiAgICAgIHRyX3N0YXRpY19pbml0KCk7CiAgICAgIHN0YXRpY19pbml0X2RvbmUgPSB0cnVlOwogICAgfQogICAgcy5sX2Rlc2MgPSBuZXcgVHJlZURlc2Mocy5keW5fbHRyZWUsIHN0YXRpY19sX2Rlc2MpOwogICAgcy5kX2Rlc2MgPSBuZXcgVHJlZURlc2Mocy5keW5fZHRyZWUsIHN0YXRpY19kX2Rlc2MpOwogICAgcy5ibF9kZXNjID0gbmV3IFRyZWVEZXNjKHMuYmxfdHJlZSwgc3RhdGljX2JsX2Rlc2MpOwogICAgcy5iaV9idWYgPSAwOwogICAgcy5iaV92YWxpZCA9IDA7CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgZmlyc3QgYmxvY2sgb2YgdGhlIGZpcnN0IGZpbGU6ICovCiAgICBpbml0X2Jsb2NrKHMpOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFNlbmQgYSBzdG9yZWQgYmxvY2sKICAgKi8KICB2YXIgX3RyX3N0b3JlZF9ibG9jayQxID0gZnVuY3Rpb24gX3RyX3N0b3JlZF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpCiAgLy9EZWZsYXRlU3RhdGUgKnM7CiAgLy9jaGFyZiAqYnVmOyAgICAgICAvKiBpbnB1dCBibG9jayAqLwogIC8vdWxnIHN0b3JlZF9sZW47ICAgLyogbGVuZ3RoIG9mIGlucHV0IGJsb2NrICovCiAgLy9pbnQgbGFzdDsgICAgICAgICAvKiBvbmUgaWYgdGhpcyBpcyB0aGUgbGFzdCBibG9jayBmb3IgYSBmaWxlICovCiAgewogICAgc2VuZF9iaXRzKHMsIChTVE9SRURfQkxPQ0sgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7IC8qIHNlbmQgYmxvY2sgdHlwZSAqLwogICAgY29weV9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIHRydWUpOyAvKiB3aXRoIGhlYWRlciAqLwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFNlbmQgb25lIGVtcHR5IHN0YXRpYyBibG9jayB0byBnaXZlIGVub3VnaCBsb29rYWhlYWQgZm9yIGluZmxhdGUuCiAgICogVGhpcyB0YWtlcyAxMCBiaXRzLCBvZiB3aGljaCA3IG1heSByZW1haW4gaW4gdGhlIGJpdCBidWZmZXIuCiAgICovCiAgdmFyIF90cl9hbGlnbiQxID0gZnVuY3Rpb24gX3RyX2FsaWduKHMpIHsKICAgIHNlbmRfYml0cyhzLCBTVEFUSUNfVFJFRVMgPDwgMSwgMyk7CiAgICBzZW5kX2NvZGUocywgRU5EX0JMT0NLLCBzdGF0aWNfbHRyZWUpOwogICAgYmlfZmx1c2gocyk7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogRGV0ZXJtaW5lIHRoZSBiZXN0IGVuY29kaW5nIGZvciB0aGUgY3VycmVudCBibG9jazogZHluYW1pYyB0cmVlcywgc3RhdGljCiAgICogdHJlZXMgb3Igc3RvcmUsIGFuZCBvdXRwdXQgdGhlIGVuY29kZWQgYmxvY2sgdG8gdGhlIHppcCBmaWxlLgogICAqLwogIHZhciBfdHJfZmx1c2hfYmxvY2skMSA9IGZ1bmN0aW9uIF90cl9mbHVzaF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpCiAgLy9EZWZsYXRlU3RhdGUgKnM7CiAgLy9jaGFyZiAqYnVmOyAgICAgICAvKiBpbnB1dCBibG9jaywgb3IgTlVMTCBpZiB0b28gb2xkICovCiAgLy91bGcgc3RvcmVkX2xlbjsgICAvKiBsZW5ndGggb2YgaW5wdXQgYmxvY2sgKi8KICAvL2ludCBsYXN0OyAgICAgICAgIC8qIG9uZSBpZiB0aGlzIGlzIHRoZSBsYXN0IGJsb2NrIGZvciBhIGZpbGUgKi8KICB7CiAgICB2YXIgb3B0X2xlbmIsIHN0YXRpY19sZW5iOyAvKiBvcHRfbGVuIGFuZCBzdGF0aWNfbGVuIGluIGJ5dGVzICovCiAgICB2YXIgbWF4X2JsaW5kZXggPSAwOyAvKiBpbmRleCBvZiBsYXN0IGJpdCBsZW5ndGggY29kZSBvZiBub24gemVybyBmcmVxICovCgogICAgLyogQnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgdW5sZXNzIGEgc3RvcmVkIGJsb2NrIGlzIGZvcmNlZCAqLwogICAgaWYgKHMubGV2ZWwgPiAwKSB7CiAgICAgIC8qIENoZWNrIGlmIHRoZSBmaWxlIGlzIGJpbmFyeSBvciB0ZXh0ICovCiAgICAgIGlmIChzLnN0cm0uZGF0YV90eXBlID09PSBaX1VOS05PV04kMSkgewogICAgICAgIHMuc3RybS5kYXRhX3R5cGUgPSBkZXRlY3RfZGF0YV90eXBlKHMpOwogICAgICB9CgogICAgICAvKiBDb25zdHJ1Y3QgdGhlIGxpdGVyYWwgYW5kIGRpc3RhbmNlIHRyZWVzICovCiAgICAgIGJ1aWxkX3RyZWUocywgcy5sX2Rlc2MpOwogICAgICAvLyBUcmFjZXYoKHN0ZGVyciwgIlxubGl0IGRhdGE6IGR5biAlbGQsIHN0YXQgJWxkIiwgcy0+b3B0X2xlbiwKICAgICAgLy8gICAgICAgIHMtPnN0YXRpY19sZW4pKTsKCiAgICAgIGJ1aWxkX3RyZWUocywgcy5kX2Rlc2MpOwogICAgICAvLyBUcmFjZXYoKHN0ZGVyciwgIlxuZGlzdCBkYXRhOiBkeW4gJWxkLCBzdGF0ICVsZCIsIHMtPm9wdF9sZW4sCiAgICAgIC8vICAgICAgICBzLT5zdGF0aWNfbGVuKSk7CiAgICAgIC8qIEF0IHRoaXMgcG9pbnQsIG9wdF9sZW4gYW5kIHN0YXRpY19sZW4gYXJlIHRoZSB0b3RhbCBiaXQgbGVuZ3RocyBvZgogICAgICAgKiB0aGUgY29tcHJlc3NlZCBibG9jayBkYXRhLCBleGNsdWRpbmcgdGhlIHRyZWUgcmVwcmVzZW50YXRpb25zLgogICAgICAgKi8KCiAgICAgIC8qIEJ1aWxkIHRoZSBiaXQgbGVuZ3RoIHRyZWUgZm9yIHRoZSBhYm92ZSB0d28gdHJlZXMsIGFuZCBnZXQgdGhlIGluZGV4CiAgICAgICAqIGluIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLgogICAgICAgKi8KICAgICAgbWF4X2JsaW5kZXggPSBidWlsZF9ibF90cmVlKHMpOwoKICAgICAgLyogRGV0ZXJtaW5lIHRoZSBiZXN0IGVuY29kaW5nLiBDb21wdXRlIHRoZSBibG9jayBsZW5ndGhzIGluIGJ5dGVzLiAqLwogICAgICBvcHRfbGVuYiA9IHMub3B0X2xlbiArIDMgKyA3ID4+PiAzOwogICAgICBzdGF0aWNfbGVuYiA9IHMuc3RhdGljX2xlbiArIDMgKyA3ID4+PiAzOwoKICAgICAgLy8gVHJhY2V2KChzdGRlcnIsICJcbm9wdCAlbHUoJWx1KSBzdGF0ICVsdSglbHUpIHN0b3JlZCAlbHUgbGl0ICV1ICIsCiAgICAgIC8vICAgICAgICBvcHRfbGVuYiwgcy0+b3B0X2xlbiwgc3RhdGljX2xlbmIsIHMtPnN0YXRpY19sZW4sIHN0b3JlZF9sZW4sCiAgICAgIC8vICAgICAgICBzLT5sYXN0X2xpdCkpOwoKICAgICAgaWYgKHN0YXRpY19sZW5iIDw9IG9wdF9sZW5iKSB7CiAgICAgICAgb3B0X2xlbmIgPSBzdGF0aWNfbGVuYjsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLy8gQXNzZXJ0KGJ1ZiAhPSAoY2hhciopMCwgImxvc3QgYnVmIik7CiAgICAgIG9wdF9sZW5iID0gc3RhdGljX2xlbmIgPSBzdG9yZWRfbGVuICsgNTsgLyogZm9yY2UgYSBzdG9yZWQgYmxvY2sgKi8KICAgIH0KICAgIGlmIChzdG9yZWRfbGVuICsgNCA8PSBvcHRfbGVuYiAmJiBidWYgIT09IC0xKSB7CiAgICAgIC8qIDQ6IHR3byB3b3JkcyBmb3IgdGhlIGxlbmd0aHMgKi8KCiAgICAgIC8qIFRoZSB0ZXN0IGJ1ZiAhPSBOVUxMIGlzIG9ubHkgbmVjZXNzYXJ5IGlmIExJVF9CVUZTSVpFID4gV1NJWkUuCiAgICAgICAqIE90aGVyd2lzZSB3ZSBjYW4ndCBoYXZlIHByb2Nlc3NlZCBtb3JlIHRoYW4gV1NJWkUgaW5wdXQgYnl0ZXMgc2luY2UKICAgICAgICogdGhlIGxhc3QgYmxvY2sgZmx1c2gsIGJlY2F1c2UgY29tcHJlc3Npb24gd291bGQgaGF2ZSBiZWVuCiAgICAgICAqIHN1Y2Nlc3NmdWwuIElmIExJVF9CVUZTSVpFIDw9IFdTSVpFLCBpdCBpcyBuZXZlciB0b28gbGF0ZSB0bwogICAgICAgKiB0cmFuc2Zvcm0gYSBibG9jayBpbnRvIGEgc3RvcmVkIGJsb2NrLgogICAgICAgKi8KICAgICAgX3RyX3N0b3JlZF9ibG9jayQxKHMsIGJ1Ziwgc3RvcmVkX2xlbiwgbGFzdCk7CiAgICB9IGVsc2UgaWYgKHMuc3RyYXRlZ3kgPT09IFpfRklYRUQkMSB8fCBzdGF0aWNfbGVuYiA9PT0gb3B0X2xlbmIpIHsKICAgICAgc2VuZF9iaXRzKHMsIChTVEFUSUNfVFJFRVMgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7CiAgICAgIGNvbXByZXNzX2Jsb2NrKHMsIHN0YXRpY19sdHJlZSwgc3RhdGljX2R0cmVlKTsKICAgIH0gZWxzZSB7CiAgICAgIHNlbmRfYml0cyhzLCAoRFlOX1RSRUVTIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpOwogICAgICBzZW5kX2FsbF90cmVlcyhzLCBzLmxfZGVzYy5tYXhfY29kZSArIDEsIHMuZF9kZXNjLm1heF9jb2RlICsgMSwgbWF4X2JsaW5kZXggKyAxKTsKICAgICAgY29tcHJlc3NfYmxvY2socywgcy5keW5fbHRyZWUsIHMuZHluX2R0cmVlKTsKICAgIH0KICAgIC8vIEFzc2VydCAocy0+Y29tcHJlc3NlZF9sZW4gPT0gcy0+Yml0c19zZW50LCAiYmFkIGNvbXByZXNzZWQgc2l6ZSIpOwogICAgLyogVGhlIGFib3ZlIGNoZWNrIGlzIG1hZGUgbW9kIDJeMzIsIGZvciBmaWxlcyBsYXJnZXIgdGhhbiA1MTIgTUIKICAgICAqIGFuZCB1TG9uZyBpbXBsZW1lbnRlZCBvbiAzMiBiaXRzLgogICAgICovCiAgICBpbml0X2Jsb2NrKHMpOwogICAgaWYgKGxhc3QpIHsKICAgICAgYmlfd2luZHVwKHMpOwogICAgfQogICAgLy8gVHJhY2V2KChzdGRlcnIsIlxuY29tcHJsZW4gJWx1KCVsdSkgIiwgcy0+Y29tcHJlc3NlZF9sZW4+PjMsCiAgICAvLyAgICAgICBzLT5jb21wcmVzc2VkX2xlbi03Kmxhc3QpKTsKICB9OwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBTYXZlIHRoZSBtYXRjaCBpbmZvIGFuZCB0YWxseSB0aGUgZnJlcXVlbmN5IGNvdW50cy4gUmV0dXJuIHRydWUgaWYKICAgKiB0aGUgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQuCiAgICovCiAgdmFyIF90cl90YWxseSQxID0gZnVuY3Rpb24gX3RyX3RhbGx5KHMsIGRpc3QsIGxjKQogIC8vICAgIGRlZmxhdGVfc3RhdGUgKnM7CiAgLy8gICAgdW5zaWduZWQgZGlzdDsgIC8qIGRpc3RhbmNlIG9mIG1hdGNoZWQgc3RyaW5nICovCiAgLy8gICAgdW5zaWduZWQgbGM7ICAgIC8qIG1hdGNoIGxlbmd0aC1NSU5fTUFUQ0ggb3IgdW5tYXRjaGVkIGNoYXIgKGlmIGRpc3Q9PTApICovCiAgewogICAgLy9sZXQgb3V0X2xlbmd0aCwgaW5fbGVuZ3RoLCBkY29kZTsKCiAgICBzLnBlbmRpbmdfYnVmW3MuZF9idWYgKyBzLmxhc3RfbGl0ICogMl0gPSBkaXN0ID4+PiA4ICYgMHhmZjsKICAgIHMucGVuZGluZ19idWZbcy5kX2J1ZiArIHMubGFzdF9saXQgKiAyICsgMV0gPSBkaXN0ICYgMHhmZjsKICAgIHMucGVuZGluZ19idWZbcy5sX2J1ZiArIHMubGFzdF9saXRdID0gbGMgJiAweGZmOwogICAgcy5sYXN0X2xpdCsrOwogICAgaWYgKGRpc3QgPT09IDApIHsKICAgICAgLyogbGMgaXMgdGhlIHVubWF0Y2hlZCBjaGFyICovCiAgICAgIHMuZHluX2x0cmVlW2xjICogMl0gLyouRnJlcSovKys7CiAgICB9IGVsc2UgewogICAgICBzLm1hdGNoZXMrKzsKICAgICAgLyogSGVyZSwgbGMgaXMgdGhlIG1hdGNoIGxlbmd0aCAtIE1JTl9NQVRDSCAqLwogICAgICBkaXN0LS07IC8qIGRpc3QgPSBtYXRjaCBkaXN0YW5jZSAtIDEgKi8KICAgICAgLy9Bc3NlcnQoKHVzaClkaXN0IDwgKHVzaClNQVhfRElTVChzKSAmJgogICAgICAvLyAgICAgICAodXNoKWxjIDw9ICh1c2gpKE1BWF9NQVRDSC1NSU5fTUFUQ0gpICYmCiAgICAgIC8vICAgICAgICh1c2gpZF9jb2RlKGRpc3QpIDwgKHVzaClEX0NPREVTLCAgIl90cl90YWxseTogYmFkIG1hdGNoIik7CgogICAgICBzLmR5bl9sdHJlZVsoX2xlbmd0aF9jb2RlW2xjXSArIExJVEVSQUxTJDEgKyAxKSAqIDJdIC8qLkZyZXEqLysrOwogICAgICBzLmR5bl9kdHJlZVtkX2NvZGUoZGlzdCkgKiAyXSAvKi5GcmVxKi8rKzsKICAgIH0KCiAgICAvLyAoISkgVGhpcyBibG9jayBpcyBkaXNhYmxlZCBpbiB6bGliIGRlZmF1bHRzLAogICAgLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eQoKICAgIC8vI2lmZGVmIFRSVU5DQVRFX0JMT0NLCiAgICAvLyAgLyogVHJ5IHRvIGd1ZXNzIGlmIGl0IGlzIHByb2ZpdGFibGUgdG8gc3RvcCB0aGUgY3VycmVudCBibG9jayBoZXJlICovCiAgICAvLyAgaWYgKChzLmxhc3RfbGl0ICYgMHgxZmZmKSA9PT0gMCAmJiBzLmxldmVsID4gMikgewogICAgLy8gICAgLyogQ29tcHV0ZSBhbiB1cHBlciBib3VuZCBmb3IgdGhlIGNvbXByZXNzZWQgbGVuZ3RoICovCiAgICAvLyAgICBvdXRfbGVuZ3RoID0gcy5sYXN0X2xpdCo4OwogICAgLy8gICAgaW5fbGVuZ3RoID0gcy5zdHJzdGFydCAtIHMuYmxvY2tfc3RhcnQ7CiAgICAvLwogICAgLy8gICAgZm9yIChkY29kZSA9IDA7IGRjb2RlIDwgRF9DT0RFUzsgZGNvZGUrKykgewogICAgLy8gICAgICBvdXRfbGVuZ3RoICs9IHMuZHluX2R0cmVlW2Rjb2RlKjJdLyouRnJlcSovICogKDUgKyBleHRyYV9kYml0c1tkY29kZV0pOwogICAgLy8gICAgfQogICAgLy8gICAgb3V0X2xlbmd0aCA+Pj49IDM7CiAgICAvLyAgICAvL1RyYWNldigoc3RkZXJyLCJcbmxhc3RfbGl0ICV1LCBpbiAlbGQsIG91dCB+JWxkKCVsZCUlKSAiLAogICAgLy8gICAgLy8gICAgICAgcy0+bGFzdF9saXQsIGluX2xlbmd0aCwgb3V0X2xlbmd0aCwKICAgIC8vICAgIC8vICAgICAgIDEwMEwgLSBvdXRfbGVuZ3RoKjEwMEwvaW5fbGVuZ3RoKSk7CiAgICAvLyAgICBpZiAocy5tYXRjaGVzIDwgKHMubGFzdF9saXQ+PjEpLyppbnQgLzIqLyAmJiBvdXRfbGVuZ3RoIDwgKGluX2xlbmd0aD4+MSkvKmludCAvMiovKSB7CiAgICAvLyAgICAgIHJldHVybiB0cnVlOwogICAgLy8gICAgfQogICAgLy8gIH0KICAgIC8vI2VuZGlmCgogICAgcmV0dXJuIHMubGFzdF9saXQgPT09IHMubGl0X2J1ZnNpemUgLSAxOwogICAgLyogV2UgYXZvaWQgZXF1YWxpdHkgd2l0aCBsaXRfYnVmc2l6ZSBiZWNhdXNlIG9mIHdyYXBhcm91bmQgYXQgNjRLCiAgICAgKiBvbiAxNiBiaXQgbWFjaGluZXMgYW5kIGJlY2F1c2Ugc3RvcmVkIGJsb2NrcyBhcmUgcmVzdHJpY3RlZCB0bwogICAgICogNjRLLTEgYnl0ZXMuCiAgICAgKi8KICB9OwogIHRyZWVzLl90cl9pbml0ID0gX3RyX2luaXQkMTsKICB0cmVlcy5fdHJfc3RvcmVkX2Jsb2NrID0gX3RyX3N0b3JlZF9ibG9jayQxOwogIHRyZWVzLl90cl9mbHVzaF9ibG9jayA9IF90cl9mbHVzaF9ibG9jayQxOwogIHRyZWVzLl90cl90YWxseSA9IF90cl90YWxseSQxOwogIHRyZWVzLl90cl9hbGlnbiA9IF90cl9hbGlnbiQxOwoKICAvLyBOb3RlOiBhZGxlcjMyIHRha2VzIDEyJSBmb3IgbGV2ZWwgMCBhbmQgMiUgZm9yIGxldmVsIDYuCiAgLy8gSXQgaXNuJ3Qgd29ydGggaXQgdG8gbWFrZSBhZGRpdGlvbmFsIG9wdGltaXphdGlvbnMgYXMgaW4gb3JpZ2luYWwuCiAgLy8gU21hbGwgc2l6ZSBpcyBwcmVmZXJhYmxlLgoKICAvLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXIKICAvLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpbgogIC8vCiAgLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICAvLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKICAvLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogIC8vCiAgLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiAgLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogIC8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKICAvLwogIC8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAgLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZQogIC8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiAgLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogIC8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiAgLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAgLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KCiAgdmFyIGFkbGVyMzIkMiA9IGZ1bmN0aW9uIGFkbGVyMzIoYWRsZXIsIGJ1ZiwgbGVuLCBwb3MpIHsKICAgIHZhciBzMSA9IGFkbGVyICYgMHhmZmZmIHwgMCwKICAgICAgczIgPSBhZGxlciA+Pj4gMTYgJiAweGZmZmYgfCAwLAogICAgICBuID0gMDsKICAgIHdoaWxlIChsZW4gIT09IDApIHsKICAgICAgLy8gU2V0IGxpbWl0IH4gdHdpY2UgbGVzcyB0aGFuIDU1NTIsIHRvIGtlZXAKICAgICAgLy8gczIgaW4gMzEtYml0cywgYmVjYXVzZSB3ZSBmb3JjZSBzaWduZWQgaW50cy4KICAgICAgLy8gaW4gb3RoZXIgY2FzZSAlPSB3aWxsIGZhaWwuCiAgICAgIG4gPSBsZW4gPiAyMDAwID8gMjAwMCA6IGxlbjsKICAgICAgbGVuIC09IG47CiAgICAgIGRvIHsKICAgICAgICBzMSA9IHMxICsgYnVmW3BvcysrXSB8IDA7CiAgICAgICAgczIgPSBzMiArIHMxIHwgMDsKICAgICAgfSB3aGlsZSAoLS1uKTsKICAgICAgczEgJT0gNjU1MjE7CiAgICAgIHMyICU9IDY1NTIxOwogICAgfQogICAgcmV0dXJuIHMxIHwgczIgPDwgMTYgfCAwOwogIH07CiAgdmFyIGFkbGVyMzJfMSA9IGFkbGVyMzIkMjsKCiAgLy8gTm90ZTogd2UgY2FuJ3QgZ2V0IHNpZ25pZmljYW50IHNwZWVkIGJvb3N0IGhlcmUuCiAgLy8gU28gd3JpdGUgY29kZSB0byBtaW5pbWl6ZSBzaXplIC0gbm8gcHJlZ2VuZXJhdGVkIHRhYmxlcwogIC8vIGFuZCBhcnJheSB0b29scyBkZXBlbmRlbmNpZXMuCgogIC8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlcgogIC8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luCiAgLy8KICAvLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAogIC8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogIC8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuCiAgLy8KICAvLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICAvLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0CiAgLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgogIC8vCiAgLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKICAvLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAgLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKICAvLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAgLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmUKICAvLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KICAvLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLgoKICAvLyBVc2Ugb3JkaW5hcnkgYXJyYXksIHNpbmNlIHVudHlwZWQgbWFrZXMgbm8gYm9vc3QgaGVyZQogIHZhciBtYWtlVGFibGUgPSBmdW5jdGlvbiBtYWtlVGFibGUoKSB7CiAgICB2YXIgYywKICAgICAgdGFibGUgPSBbXTsKICAgIGZvciAodmFyIG4gPSAwOyBuIDwgMjU2OyBuKyspIHsKICAgICAgYyA9IG47CiAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgODsgaysrKSB7CiAgICAgICAgYyA9IGMgJiAxID8gMHhFREI4ODMyMCBeIGMgPj4+IDEgOiBjID4+PiAxOwogICAgICB9CiAgICAgIHRhYmxlW25dID0gYzsKICAgIH0KICAgIHJldHVybiB0YWJsZTsKICB9OwoKICAvLyBDcmVhdGUgdGFibGUgb24gbG9hZC4gSnVzdCAyNTUgc2lnbmVkIGxvbmdzLiBOb3QgYSBwcm9ibGVtLgogIHZhciBjcmNUYWJsZSA9IG5ldyBVaW50MzJBcnJheShtYWtlVGFibGUoKSk7CiAgdmFyIGNyYzMyJDIgPSBmdW5jdGlvbiBjcmMzMihjcmMsIGJ1ZiwgbGVuLCBwb3MpIHsKICAgIHZhciB0ID0gY3JjVGFibGU7CiAgICB2YXIgZW5kID0gcG9zICsgbGVuOwogICAgY3JjIF49IC0xOwogICAgZm9yICh2YXIgaSA9IHBvczsgaSA8IGVuZDsgaSsrKSB7CiAgICAgIGNyYyA9IGNyYyA+Pj4gOCBeIHRbKGNyYyBeIGJ1ZltpXSkgJiAweEZGXTsKICAgIH0KICAgIHJldHVybiBjcmMgXiAtMTsgLy8gPj4+IDA7CiAgfTsKICB2YXIgY3JjMzJfMSA9IGNyYzMyJDI7CgogIC8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlcgogIC8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luCiAgLy8KICAvLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAogIC8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogIC8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuCiAgLy8KICAvLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICAvLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0CiAgLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgogIC8vCiAgLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKICAvLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAgLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKICAvLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAgLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmUKICAvLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KICAvLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLgoKICB2YXIgbWVzc2FnZXMgPSB7CiAgICAyOiAnbmVlZCBkaWN0aW9uYXJ5JywKICAgIC8qIFpfTkVFRF9ESUNUICAgICAgIDIgICovCiAgICAxOiAnc3RyZWFtIGVuZCcsCiAgICAvKiBaX1NUUkVBTV9FTkQgICAgICAxICAqLwogICAgMDogJycsCiAgICAvKiBaX09LICAgICAgICAgICAgICAwICAqLwogICAgJy0xJzogJ2ZpbGUgZXJyb3InLAogICAgLyogWl9FUlJOTyAgICAgICAgICgtMSkgKi8KICAgICctMic6ICdzdHJlYW0gZXJyb3InLAogICAgLyogWl9TVFJFQU1fRVJST1IgICgtMikgKi8KICAgICctMyc6ICdkYXRhIGVycm9yJywKICAgIC8qIFpfREFUQV9FUlJPUiAgICAoLTMpICovCiAgICAnLTQnOiAnaW5zdWZmaWNpZW50IG1lbW9yeScsCiAgICAvKiBaX01FTV9FUlJPUiAgICAgKC00KSAqLwogICAgJy01JzogJ2J1ZmZlciBlcnJvcicsCiAgICAvKiBaX0JVRl9FUlJPUiAgICAgKC01KSAqLwogICAgJy02JzogJ2luY29tcGF0aWJsZSB2ZXJzaW9uJyAvKiBaX1ZFUlNJT05fRVJST1IgKC02KSAqLwogIH07CgogIC8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlcgogIC8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luCiAgLy8KICAvLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAogIC8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogIC8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuCiAgLy8KICAvLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICAvLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0CiAgLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgogIC8vCiAgLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKICAvLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAgLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKICAvLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAgLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmUKICAvLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KICAvLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLgoKICB2YXIgY29uc3RhbnRzJDEgPSB7CiAgICAvKiBBbGxvd2VkIGZsdXNoIHZhbHVlczsgc2VlIGRlZmxhdGUoKSBhbmQgaW5mbGF0ZSgpIGJlbG93IGZvciBkZXRhaWxzICovCiAgICBaX05PX0ZMVVNIOiAwLAogICAgWl9QQVJUSUFMX0ZMVVNIOiAxLAogICAgWl9TWU5DX0ZMVVNIOiAyLAogICAgWl9GVUxMX0ZMVVNIOiAzLAogICAgWl9GSU5JU0g6IDQsCiAgICBaX0JMT0NLOiA1LAogICAgWl9UUkVFUzogNiwKICAgIC8qIFJldHVybiBjb2RlcyBmb3IgdGhlIGNvbXByZXNzaW9uL2RlY29tcHJlc3Npb24gZnVuY3Rpb25zLiBOZWdhdGl2ZSB2YWx1ZXMKICAgICogYXJlIGVycm9ycywgcG9zaXRpdmUgdmFsdWVzIGFyZSB1c2VkIGZvciBzcGVjaWFsIGJ1dCBub3JtYWwgZXZlbnRzLgogICAgKi8KICAgIFpfT0s6IDAsCiAgICBaX1NUUkVBTV9FTkQ6IDEsCiAgICBaX05FRURfRElDVDogMiwKICAgIFpfRVJSTk86IC0xLAogICAgWl9TVFJFQU1fRVJST1I6IC0yLAogICAgWl9EQVRBX0VSUk9SOiAtMywKICAgIFpfTUVNX0VSUk9SOiAtNCwKICAgIFpfQlVGX0VSUk9SOiAtNSwKICAgIC8vWl9WRVJTSU9OX0VSUk9SOiAtNiwKCiAgICAvKiBjb21wcmVzc2lvbiBsZXZlbHMgKi8KICAgIFpfTk9fQ09NUFJFU1NJT046IDAsCiAgICBaX0JFU1RfU1BFRUQ6IDEsCiAgICBaX0JFU1RfQ09NUFJFU1NJT046IDksCiAgICBaX0RFRkFVTFRfQ09NUFJFU1NJT046IC0xLAogICAgWl9GSUxURVJFRDogMSwKICAgIFpfSFVGRk1BTl9PTkxZOiAyLAogICAgWl9STEU6IDMsCiAgICBaX0ZJWEVEOiA0LAogICAgWl9ERUZBVUxUX1NUUkFURUdZOiAwLAogICAgLyogUG9zc2libGUgdmFsdWVzIG9mIHRoZSBkYXRhX3R5cGUgZmllbGQgKHRob3VnaCBzZWUgaW5mbGF0ZSgpKSAqLwogICAgWl9CSU5BUlk6IDAsCiAgICBaX1RFWFQ6IDEsCiAgICAvL1pfQVNDSUk6ICAgICAgICAgICAgICAgIDEsIC8vID0gWl9URVhUIChkZXByZWNhdGVkKQogICAgWl9VTktOT1dOOiAyLAogICAgLyogVGhlIGRlZmxhdGUgY29tcHJlc3Npb24gbWV0aG9kICovCiAgICBaX0RFRkxBVEVEOiA4CiAgICAvL1pfTlVMTDogICAgICAgICAgICAgICAgIG51bGwgLy8gVXNlIC0xIG9yIG51bGwgaW5saW5lLCBkZXBlbmRpbmcgb24gdmFyIHR5cGUKICB9OwoKICAvLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXIKICAvLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpbgogIC8vCiAgLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICAvLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKICAvLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogIC8vCiAgLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiAgLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogIC8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKICAvLwogIC8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAgLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZQogIC8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiAgLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogIC8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiAgLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAgLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KCiAgdmFyIF90cl9pbml0ID0gdHJlZXMuX3RyX2luaXQsCiAgICBfdHJfc3RvcmVkX2Jsb2NrID0gdHJlZXMuX3RyX3N0b3JlZF9ibG9jaywKICAgIF90cl9mbHVzaF9ibG9jayA9IHRyZWVzLl90cl9mbHVzaF9ibG9jaywKICAgIF90cl90YWxseSA9IHRyZWVzLl90cl90YWxseSwKICAgIF90cl9hbGlnbiA9IHRyZWVzLl90cl9hbGlnbjsKICB2YXIgYWRsZXIzMiQxID0gYWRsZXIzMl8xOwogIHZhciBjcmMzMiQxID0gY3JjMzJfMTsKICB2YXIgbXNnJDIgPSBtZXNzYWdlczsKCiAgLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKICB2YXIgWl9OT19GTFVTSCQyID0gY29uc3RhbnRzJDEuWl9OT19GTFVTSCwKICAgIFpfUEFSVElBTF9GTFVTSCA9IGNvbnN0YW50cyQxLlpfUEFSVElBTF9GTFVTSCwKICAgIFpfRlVMTF9GTFVTSCQxID0gY29uc3RhbnRzJDEuWl9GVUxMX0ZMVVNILAogICAgWl9GSU5JU0gkMyA9IGNvbnN0YW50cyQxLlpfRklOSVNILAogICAgWl9CTE9DSyQxID0gY29uc3RhbnRzJDEuWl9CTE9DSywKICAgIFpfT0skMyA9IGNvbnN0YW50cyQxLlpfT0ssCiAgICBaX1NUUkVBTV9FTkQkMyA9IGNvbnN0YW50cyQxLlpfU1RSRUFNX0VORCwKICAgIFpfU1RSRUFNX0VSUk9SJDIgPSBjb25zdGFudHMkMS5aX1NUUkVBTV9FUlJPUiwKICAgIFpfREFUQV9FUlJPUiQyID0gY29uc3RhbnRzJDEuWl9EQVRBX0VSUk9SLAogICAgWl9CVUZfRVJST1IkMSA9IGNvbnN0YW50cyQxLlpfQlVGX0VSUk9SLAogICAgWl9ERUZBVUxUX0NPTVBSRVNTSU9OJDEgPSBjb25zdGFudHMkMS5aX0RFRkFVTFRfQ09NUFJFU1NJT04sCiAgICBaX0ZJTFRFUkVEID0gY29uc3RhbnRzJDEuWl9GSUxURVJFRCwKICAgIFpfSFVGRk1BTl9PTkxZID0gY29uc3RhbnRzJDEuWl9IVUZGTUFOX09OTFksCiAgICBaX1JMRSA9IGNvbnN0YW50cyQxLlpfUkxFLAogICAgWl9GSVhFRCA9IGNvbnN0YW50cyQxLlpfRklYRUQsCiAgICBaX0RFRkFVTFRfU1RSQVRFR1kkMSA9IGNvbnN0YW50cyQxLlpfREVGQVVMVF9TVFJBVEVHWSwKICAgIFpfVU5LTk9XTiA9IGNvbnN0YW50cyQxLlpfVU5LTk9XTiwKICAgIFpfREVGTEFURUQkMiA9IGNvbnN0YW50cyQxLlpfREVGTEFURUQ7CgogIC8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCgogIHZhciBNQVhfTUVNX0xFVkVMID0gOTsKICAvKiBNYXhpbXVtIHZhbHVlIGZvciBtZW1MZXZlbCBpbiBkZWZsYXRlSW5pdDIgKi8KICB2YXIgTUFYX1dCSVRTJDEgPSAxNTsKICAvKiAzMksgTFo3NyB3aW5kb3cgKi8KICB2YXIgREVGX01FTV9MRVZFTCA9IDg7CiAgdmFyIExFTkdUSF9DT0RFUyA9IDI5OwogIC8qIG51bWJlciBvZiBsZW5ndGggY29kZXMsIG5vdCBjb3VudGluZyB0aGUgc3BlY2lhbCBFTkRfQkxPQ0sgY29kZSAqLwogIHZhciBMSVRFUkFMUyA9IDI1NjsKICAvKiBudW1iZXIgb2YgbGl0ZXJhbCBieXRlcyAwLi4yNTUgKi8KICB2YXIgTF9DT0RFUyA9IExJVEVSQUxTICsgMSArIExFTkdUSF9DT0RFUzsKICAvKiBudW1iZXIgb2YgTGl0ZXJhbCBvciBMZW5ndGggY29kZXMsIGluY2x1ZGluZyB0aGUgRU5EX0JMT0NLIGNvZGUgKi8KICB2YXIgRF9DT0RFUyA9IDMwOwogIC8qIG51bWJlciBvZiBkaXN0YW5jZSBjb2RlcyAqLwogIHZhciBCTF9DT0RFUyA9IDE5OwogIC8qIG51bWJlciBvZiBjb2RlcyB1c2VkIHRvIHRyYW5zZmVyIHRoZSBiaXQgbGVuZ3RocyAqLwogIHZhciBIRUFQX1NJWkUgPSAyICogTF9DT0RFUyArIDE7CiAgLyogbWF4aW11bSBoZWFwIHNpemUgKi8KICB2YXIgTUFYX0JJVFMgPSAxNTsKICAvKiBBbGwgY29kZXMgbXVzdCBub3QgZXhjZWVkIE1BWF9CSVRTIGJpdHMgKi8KCiAgdmFyIE1JTl9NQVRDSCA9IDM7CiAgdmFyIE1BWF9NQVRDSCA9IDI1ODsKICB2YXIgTUlOX0xPT0tBSEVBRCA9IE1BWF9NQVRDSCArIE1JTl9NQVRDSCArIDE7CiAgdmFyIFBSRVNFVF9ESUNUID0gMHgyMDsKICB2YXIgSU5JVF9TVEFURSA9IDQyOwogIHZhciBFWFRSQV9TVEFURSA9IDY5OwogIHZhciBOQU1FX1NUQVRFID0gNzM7CiAgdmFyIENPTU1FTlRfU1RBVEUgPSA5MTsKICB2YXIgSENSQ19TVEFURSA9IDEwMzsKICB2YXIgQlVTWV9TVEFURSA9IDExMzsKICB2YXIgRklOSVNIX1NUQVRFID0gNjY2OwogIHZhciBCU19ORUVEX01PUkUgPSAxOyAvKiBibG9jayBub3QgY29tcGxldGVkLCBuZWVkIG1vcmUgaW5wdXQgb3IgbW9yZSBvdXRwdXQgKi8KICB2YXIgQlNfQkxPQ0tfRE9ORSA9IDI7IC8qIGJsb2NrIGZsdXNoIHBlcmZvcm1lZCAqLwogIHZhciBCU19GSU5JU0hfU1RBUlRFRCA9IDM7IC8qIGZpbmlzaCBzdGFydGVkLCBuZWVkIG9ubHkgbW9yZSBvdXRwdXQgYXQgbmV4dCBkZWZsYXRlICovCiAgdmFyIEJTX0ZJTklTSF9ET05FID0gNDsgLyogZmluaXNoIGRvbmUsIGFjY2VwdCBubyBtb3JlIGlucHV0IG9yIG91dHB1dCAqLwoKICB2YXIgT1NfQ09ERSA9IDB4MDM7IC8vIFVuaXggOikgLiBEb24ndCBkZXRlY3QsIHVzZSB0aGlzIGRlZmF1bHQuCgogIHZhciBlcnIgPSBmdW5jdGlvbiBlcnIoc3RybSwgZXJyb3JDb2RlKSB7CiAgICBzdHJtLm1zZyA9IG1zZyQyW2Vycm9yQ29kZV07CiAgICByZXR1cm4gZXJyb3JDb2RlOwogIH07CiAgdmFyIHJhbmsgPSBmdW5jdGlvbiByYW5rKGYpIHsKICAgIHJldHVybiAoZiA8PCAxKSAtIChmID4gNCA/IDkgOiAwKTsKICB9OwogIHZhciB6ZXJvID0gZnVuY3Rpb24gemVybyhidWYpIHsKICAgIHZhciBsZW4gPSBidWYubGVuZ3RoOwogICAgd2hpbGUgKC0tbGVuID49IDApIHsKICAgICAgYnVmW2xlbl0gPSAwOwogICAgfQogIH07CgogIC8qIGVzbGludC1kaXNhYmxlIG5ldy1jYXAgKi8KICB2YXIgSEFTSF9aTElCID0gZnVuY3Rpb24gSEFTSF9aTElCKHMsIHByZXYsIGRhdGEpIHsKICAgIHJldHVybiAocHJldiA8PCBzLmhhc2hfc2hpZnQgXiBkYXRhKSAmIHMuaGFzaF9tYXNrOwogIH07CiAgLy8gVGhpcyBoYXNoIGNhdXNlcyBsZXNzIGNvbGxpc2lvbnMsIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGFrby9pc3N1ZXMvMTM1CiAgLy8gQnV0IGJyZWFrcyBiaW5hcnkgY29tcGF0aWJpbGl0eQogIC8vbGV0IEhBU0hfRkFTVCA9IChzLCBwcmV2LCBkYXRhKSA9PiAoKHByZXYgPDwgOCkgKyAocHJldiA+PiA4KSArIChkYXRhIDw8IDQpKSAmIHMuaGFzaF9tYXNrOwogIHZhciBIQVNIID0gSEFTSF9aTElCOwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogRmx1c2ggYXMgbXVjaCBwZW5kaW5nIG91dHB1dCBhcyBwb3NzaWJsZS4gQWxsIGRlZmxhdGUoKSBvdXRwdXQgZ29lcwogICAqIHRocm91Z2ggdGhpcyBmdW5jdGlvbiBzbyBzb21lIGFwcGxpY2F0aW9ucyBtYXkgd2lzaCB0byBtb2RpZnkgaXQKICAgKiB0byBhdm9pZCBhbGxvY2F0aW5nIGEgbGFyZ2Ugc3RybS0+b3V0cHV0IGJ1ZmZlciBhbmQgY29weWluZyBpbnRvIGl0LgogICAqIChTZWUgYWxzbyByZWFkX2J1ZigpKS4KICAgKi8KICB2YXIgZmx1c2hfcGVuZGluZyA9IGZ1bmN0aW9uIGZsdXNoX3BlbmRpbmcoc3RybSkgewogICAgdmFyIHMgPSBzdHJtLnN0YXRlOwoKICAgIC8vX3RyX2ZsdXNoX2JpdHMocyk7CiAgICB2YXIgbGVuID0gcy5wZW5kaW5nOwogICAgaWYgKGxlbiA+IHN0cm0uYXZhaWxfb3V0KSB7CiAgICAgIGxlbiA9IHN0cm0uYXZhaWxfb3V0OwogICAgfQogICAgaWYgKGxlbiA9PT0gMCkgewogICAgICByZXR1cm47CiAgICB9CiAgICBzdHJtLm91dHB1dC5zZXQocy5wZW5kaW5nX2J1Zi5zdWJhcnJheShzLnBlbmRpbmdfb3V0LCBzLnBlbmRpbmdfb3V0ICsgbGVuKSwgc3RybS5uZXh0X291dCk7CiAgICBzdHJtLm5leHRfb3V0ICs9IGxlbjsKICAgIHMucGVuZGluZ19vdXQgKz0gbGVuOwogICAgc3RybS50b3RhbF9vdXQgKz0gbGVuOwogICAgc3RybS5hdmFpbF9vdXQgLT0gbGVuOwogICAgcy5wZW5kaW5nIC09IGxlbjsKICAgIGlmIChzLnBlbmRpbmcgPT09IDApIHsKICAgICAgcy5wZW5kaW5nX291dCA9IDA7CiAgICB9CiAgfTsKICB2YXIgZmx1c2hfYmxvY2tfb25seSA9IGZ1bmN0aW9uIGZsdXNoX2Jsb2NrX29ubHkocywgbGFzdCkgewogICAgX3RyX2ZsdXNoX2Jsb2NrKHMsIHMuYmxvY2tfc3RhcnQgPj0gMCA/IHMuYmxvY2tfc3RhcnQgOiAtMSwgcy5zdHJzdGFydCAtIHMuYmxvY2tfc3RhcnQsIGxhc3QpOwogICAgcy5ibG9ja19zdGFydCA9IHMuc3Ryc3RhcnQ7CiAgICBmbHVzaF9wZW5kaW5nKHMuc3RybSk7CiAgfTsKICB2YXIgcHV0X2J5dGUgPSBmdW5jdGlvbiBwdXRfYnl0ZShzLCBiKSB7CiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IGI7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFB1dCBhIHNob3J0IGluIHRoZSBwZW5kaW5nIGJ1ZmZlci4gVGhlIDE2LWJpdCB2YWx1ZSBpcyBwdXQgaW4gTVNCIG9yZGVyLgogICAqIElOIGFzc2VydGlvbjogdGhlIHN0cmVhbSBzdGF0ZSBpcyBjb3JyZWN0IGFuZCB0aGVyZSBpcyBlbm91Z2ggcm9vbSBpbgogICAqIHBlbmRpbmdfYnVmLgogICAqLwogIHZhciBwdXRTaG9ydE1TQiA9IGZ1bmN0aW9uIHB1dFNob3J0TVNCKHMsIGIpIHsKICAgIC8vICBwdXRfYnl0ZShzLCAoQnl0ZSkoYiA+PiA4KSk7CiAgICAvLyAgcHV0X2J5dGUocywgKEJ5dGUpKGIgJiAweGZmKSk7CiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IGIgPj4+IDggJiAweGZmOwogICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBiICYgMHhmZjsKICB9OwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBSZWFkIGEgbmV3IGJ1ZmZlciBmcm9tIHRoZSBjdXJyZW50IGlucHV0IHN0cmVhbSwgdXBkYXRlIHRoZSBhZGxlcjMyCiAgICogYW5kIHRvdGFsIG51bWJlciBvZiBieXRlcyByZWFkLiAgQWxsIGRlZmxhdGUoKSBpbnB1dCBnb2VzIHRocm91Z2gKICAgKiB0aGlzIGZ1bmN0aW9uIHNvIHNvbWUgYXBwbGljYXRpb25zIG1heSB3aXNoIHRvIG1vZGlmeSBpdCB0byBhdm9pZAogICAqIGFsbG9jYXRpbmcgYSBsYXJnZSBzdHJtLT5pbnB1dCBidWZmZXIgYW5kIGNvcHlpbmcgZnJvbSBpdC4KICAgKiAoU2VlIGFsc28gZmx1c2hfcGVuZGluZygpKS4KICAgKi8KICB2YXIgcmVhZF9idWYgPSBmdW5jdGlvbiByZWFkX2J1ZihzdHJtLCBidWYsIHN0YXJ0LCBzaXplKSB7CiAgICB2YXIgbGVuID0gc3RybS5hdmFpbF9pbjsKICAgIGlmIChsZW4gPiBzaXplKSB7CiAgICAgIGxlbiA9IHNpemU7CiAgICB9CiAgICBpZiAobGVuID09PSAwKSB7CiAgICAgIHJldHVybiAwOwogICAgfQogICAgc3RybS5hdmFpbF9pbiAtPSBsZW47CgogICAgLy8gem1lbWNweShidWYsIHN0cm0tPm5leHRfaW4sIGxlbik7CiAgICBidWYuc2V0KHN0cm0uaW5wdXQuc3ViYXJyYXkoc3RybS5uZXh0X2luLCBzdHJtLm5leHRfaW4gKyBsZW4pLCBzdGFydCk7CiAgICBpZiAoc3RybS5zdGF0ZS53cmFwID09PSAxKSB7CiAgICAgIHN0cm0uYWRsZXIgPSBhZGxlcjMyJDEoc3RybS5hZGxlciwgYnVmLCBsZW4sIHN0YXJ0KTsKICAgIH0gZWxzZSBpZiAoc3RybS5zdGF0ZS53cmFwID09PSAyKSB7CiAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMiQxKHN0cm0uYWRsZXIsIGJ1ZiwgbGVuLCBzdGFydCk7CiAgICB9CiAgICBzdHJtLm5leHRfaW4gKz0gbGVuOwogICAgc3RybS50b3RhbF9pbiArPSBsZW47CiAgICByZXR1cm4gbGVuOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFNldCBtYXRjaF9zdGFydCB0byB0aGUgbG9uZ2VzdCBtYXRjaCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gc3RyaW5nIGFuZAogICAqIHJldHVybiBpdHMgbGVuZ3RoLiBNYXRjaGVzIHNob3J0ZXIgb3IgZXF1YWwgdG8gcHJldl9sZW5ndGggYXJlIGRpc2NhcmRlZCwKICAgKiBpbiB3aGljaCBjYXNlIHRoZSByZXN1bHQgaXMgZXF1YWwgdG8gcHJldl9sZW5ndGggYW5kIG1hdGNoX3N0YXJ0IGlzCiAgICogZ2FyYmFnZS4KICAgKiBJTiBhc3NlcnRpb25zOiBjdXJfbWF0Y2ggaXMgdGhlIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW4gZm9yIHRoZSBjdXJyZW50CiAgICogICBzdHJpbmcgKHN0cnN0YXJ0KSBhbmQgaXRzIGRpc3RhbmNlIGlzIDw9IE1BWF9ESVNULCBhbmQgcHJldl9sZW5ndGggPj0gMQogICAqIE9VVCBhc3NlcnRpb246IHRoZSBtYXRjaCBsZW5ndGggaXMgbm90IGdyZWF0ZXIgdGhhbiBzLT5sb29rYWhlYWQuCiAgICovCiAgdmFyIGxvbmdlc3RfbWF0Y2ggPSBmdW5jdGlvbiBsb25nZXN0X21hdGNoKHMsIGN1cl9tYXRjaCkgewogICAgdmFyIGNoYWluX2xlbmd0aCA9IHMubWF4X2NoYWluX2xlbmd0aDsgLyogbWF4IGhhc2ggY2hhaW4gbGVuZ3RoICovCiAgICB2YXIgc2NhbiA9IHMuc3Ryc3RhcnQ7IC8qIGN1cnJlbnQgc3RyaW5nICovCiAgICB2YXIgbWF0Y2g7IC8qIG1hdGNoZWQgc3RyaW5nICovCiAgICB2YXIgbGVuOyAvKiBsZW5ndGggb2YgY3VycmVudCBtYXRjaCAqLwogICAgdmFyIGJlc3RfbGVuID0gcy5wcmV2X2xlbmd0aDsgLyogYmVzdCBtYXRjaCBsZW5ndGggc28gZmFyICovCiAgICB2YXIgbmljZV9tYXRjaCA9IHMubmljZV9tYXRjaDsgLyogc3RvcCBpZiBtYXRjaCBsb25nIGVub3VnaCAqLwogICAgdmFyIGxpbWl0ID0gcy5zdHJzdGFydCA+IHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCA/IHMuc3Ryc3RhcnQgLSAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSA6IDAgLypOSUwqLzsKICAgIHZhciBfd2luID0gcy53aW5kb3c7IC8vIHNob3J0Y3V0CgogICAgdmFyIHdtYXNrID0gcy53X21hc2s7CiAgICB2YXIgcHJldiA9IHMucHJldjsKCiAgICAvKiBTdG9wIHdoZW4gY3VyX21hdGNoIGJlY29tZXMgPD0gbGltaXQuIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLAogICAgICogd2UgcHJldmVudCBtYXRjaGVzIHdpdGggdGhlIHN0cmluZyBvZiB3aW5kb3cgaW5kZXggMC4KICAgICAqLwoKICAgIHZhciBzdHJlbmQgPSBzLnN0cnN0YXJ0ICsgTUFYX01BVENIOwogICAgdmFyIHNjYW5fZW5kMSA9IF93aW5bc2NhbiArIGJlc3RfbGVuIC0gMV07CiAgICB2YXIgc2Nhbl9lbmQgPSBfd2luW3NjYW4gKyBiZXN0X2xlbl07CgogICAgLyogVGhlIGNvZGUgaXMgb3B0aW1pemVkIGZvciBIQVNIX0JJVFMgPj0gOCBhbmQgTUFYX01BVENILTIgbXVsdGlwbGUgb2YgMTYuCiAgICAgKiBJdCBpcyBlYXN5IHRvIGdldCByaWQgb2YgdGhpcyBvcHRpbWl6YXRpb24gaWYgbmVjZXNzYXJ5LgogICAgICovCiAgICAvLyBBc3NlcnQocy0+aGFzaF9iaXRzID49IDggJiYgTUFYX01BVENIID09IDI1OCwgIkNvZGUgdG9vIGNsZXZlciIpOwoKICAgIC8qIERvIG5vdCB3YXN0ZSB0b28gbXVjaCB0aW1lIGlmIHdlIGFscmVhZHkgaGF2ZSBhIGdvb2QgbWF0Y2g6ICovCiAgICBpZiAocy5wcmV2X2xlbmd0aCA+PSBzLmdvb2RfbWF0Y2gpIHsKICAgICAgY2hhaW5fbGVuZ3RoID4+PSAyOwogICAgfQogICAgLyogRG8gbm90IGxvb2sgZm9yIG1hdGNoZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIGlucHV0LiBUaGlzIGlzIG5lY2Vzc2FyeQogICAgICogdG8gbWFrZSBkZWZsYXRlIGRldGVybWluaXN0aWMuCiAgICAgKi8KICAgIGlmIChuaWNlX21hdGNoID4gcy5sb29rYWhlYWQpIHsKICAgICAgbmljZV9tYXRjaCA9IHMubG9va2FoZWFkOwogICAgfQoKICAgIC8vIEFzc2VydCgodWxnKXMtPnN0cnN0YXJ0IDw9IHMtPndpbmRvd19zaXplLU1JTl9MT09LQUhFQUQsICJuZWVkIGxvb2thaGVhZCIpOwoKICAgIGRvIHsKICAgICAgLy8gQXNzZXJ0KGN1cl9tYXRjaCA8IHMtPnN0cnN0YXJ0LCAibm8gZnV0dXJlIik7CiAgICAgIG1hdGNoID0gY3VyX21hdGNoOwoKICAgICAgLyogU2tpcCB0byBuZXh0IG1hdGNoIGlmIHRoZSBtYXRjaCBsZW5ndGggY2Fubm90IGluY3JlYXNlCiAgICAgICAqIG9yIGlmIHRoZSBtYXRjaCBsZW5ndGggaXMgbGVzcyB0aGFuIDIuICBOb3RlIHRoYXQgdGhlIGNoZWNrcyBiZWxvdwogICAgICAgKiBmb3IgaW5zdWZmaWNpZW50IGxvb2thaGVhZCBvbmx5IG9jY3VyIG9jY2FzaW9uYWxseSBmb3IgcGVyZm9ybWFuY2UKICAgICAgICogcmVhc29ucy4gIFRoZXJlZm9yZSB1bmluaXRpYWxpemVkIG1lbW9yeSB3aWxsIGJlIGFjY2Vzc2VkLCBhbmQKICAgICAgICogY29uZGl0aW9uYWwganVtcHMgd2lsbCBiZSBtYWRlIHRoYXQgZGVwZW5kIG9uIHRob3NlIHZhbHVlcy4KICAgICAgICogSG93ZXZlciB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaCBpcyBsaW1pdGVkIHRvIHRoZSBsb29rYWhlYWQsIHNvCiAgICAgICAqIHRoZSBvdXRwdXQgb2YgZGVmbGF0ZSBpcyBub3QgYWZmZWN0ZWQgYnkgdGhlIHVuaW5pdGlhbGl6ZWQgdmFsdWVzLgogICAgICAgKi8KCiAgICAgIGlmIChfd2luW21hdGNoICsgYmVzdF9sZW5dICE9PSBzY2FuX2VuZCB8fCBfd2luW21hdGNoICsgYmVzdF9sZW4gLSAxXSAhPT0gc2Nhbl9lbmQxIHx8IF93aW5bbWF0Y2hdICE9PSBfd2luW3NjYW5dIHx8IF93aW5bKyttYXRjaF0gIT09IF93aW5bc2NhbiArIDFdKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KCiAgICAgIC8qIFRoZSBjaGVjayBhdCBiZXN0X2xlbi0xIGNhbiBiZSByZW1vdmVkIGJlY2F1c2UgaXQgd2lsbCBiZSBtYWRlCiAgICAgICAqIGFnYWluIGxhdGVyLiAoVGhpcyBoZXVyaXN0aWMgaXMgbm90IGFsd2F5cyBhIHdpbi4pCiAgICAgICAqIEl0IGlzIG5vdCBuZWNlc3NhcnkgdG8gY29tcGFyZSBzY2FuWzJdIGFuZCBtYXRjaFsyXSBzaW5jZSB0aGV5CiAgICAgICAqIGFyZSBhbHdheXMgZXF1YWwgd2hlbiB0aGUgb3RoZXIgYnl0ZXMgbWF0Y2gsIGdpdmVuIHRoYXQKICAgICAgICogdGhlIGhhc2gga2V5cyBhcmUgZXF1YWwgYW5kIHRoYXQgSEFTSF9CSVRTID49IDguCiAgICAgICAqLwogICAgICBzY2FuICs9IDI7CiAgICAgIG1hdGNoKys7CiAgICAgIC8vIEFzc2VydCgqc2NhbiA9PSAqbWF0Y2gsICJtYXRjaFsyXT8iKTsKCiAgICAgIC8qIFdlIGNoZWNrIGZvciBpbnN1ZmZpY2llbnQgbG9va2FoZWFkIG9ubHkgZXZlcnkgOHRoIGNvbXBhcmlzb247CiAgICAgICAqIHRoZSAyNTZ0aCBjaGVjayB3aWxsIGJlIG1hZGUgYXQgc3Ryc3RhcnQrMjU4LgogICAgICAgKi8KICAgICAgZG8gewogICAgICAgIC8qanNoaW50IG5vZW1wdHk6ZmFsc2UqLwogICAgICB9IHdoaWxlIChfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIHNjYW4gPCBzdHJlbmQpOwoKICAgICAgLy8gQXNzZXJ0KHNjYW4gPD0gcy0+d2luZG93Kyh1bnNpZ25lZCkocy0+d2luZG93X3NpemUtMSksICJ3aWxkIHNjYW4iKTsKCiAgICAgIGxlbiA9IE1BWF9NQVRDSCAtIChzdHJlbmQgLSBzY2FuKTsKICAgICAgc2NhbiA9IHN0cmVuZCAtIE1BWF9NQVRDSDsKICAgICAgaWYgKGxlbiA+IGJlc3RfbGVuKSB7CiAgICAgICAgcy5tYXRjaF9zdGFydCA9IGN1cl9tYXRjaDsKICAgICAgICBiZXN0X2xlbiA9IGxlbjsKICAgICAgICBpZiAobGVuID49IG5pY2VfbWF0Y2gpIHsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBzY2FuX2VuZDEgPSBfd2luW3NjYW4gKyBiZXN0X2xlbiAtIDFdOwogICAgICAgIHNjYW5fZW5kID0gX3dpbltzY2FuICsgYmVzdF9sZW5dOwogICAgICB9CiAgICB9IHdoaWxlICgoY3VyX21hdGNoID0gcHJldltjdXJfbWF0Y2ggJiB3bWFza10pID4gbGltaXQgJiYgLS1jaGFpbl9sZW5ndGggIT09IDApOwogICAgaWYgKGJlc3RfbGVuIDw9IHMubG9va2FoZWFkKSB7CiAgICAgIHJldHVybiBiZXN0X2xlbjsKICAgIH0KICAgIHJldHVybiBzLmxvb2thaGVhZDsKICB9OwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBGaWxsIHRoZSB3aW5kb3cgd2hlbiB0aGUgbG9va2FoZWFkIGJlY29tZXMgaW5zdWZmaWNpZW50LgogICAqIFVwZGF0ZXMgc3Ryc3RhcnQgYW5kIGxvb2thaGVhZC4KICAgKgogICAqIElOIGFzc2VydGlvbjogbG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRAogICAqIE9VVCBhc3NlcnRpb25zOiBzdHJzdGFydCA8PSB3aW5kb3dfc2l6ZS1NSU5fTE9PS0FIRUFECiAgICogICAgQXQgbGVhc3Qgb25lIGJ5dGUgaGFzIGJlZW4gcmVhZCwgb3IgYXZhaWxfaW4gPT0gMDsgcmVhZHMgYXJlCiAgICogICAgcGVyZm9ybWVkIGZvciBhdCBsZWFzdCB0d28gYnl0ZXMgKHJlcXVpcmVkIGZvciB0aGUgemlwIHRyYW5zbGF0ZV9lb2wKICAgKiAgICBvcHRpb24gLS0gbm90IHN1cHBvcnRlZCBoZXJlKS4KICAgKi8KICB2YXIgZmlsbF93aW5kb3cgPSBmdW5jdGlvbiBmaWxsX3dpbmRvdyhzKSB7CiAgICB2YXIgX3dfc2l6ZSA9IHMud19zaXplOwogICAgdmFyIHAsIG4sIG0sIG1vcmUsIHN0cjsKCiAgICAvL0Fzc2VydChzLT5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFELCAiYWxyZWFkeSBlbm91Z2ggbG9va2FoZWFkIik7CgogICAgZG8gewogICAgICBtb3JlID0gcy53aW5kb3dfc2l6ZSAtIHMubG9va2FoZWFkIC0gcy5zdHJzdGFydDsKCiAgICAgIC8vIEpTIGludHMgaGF2ZSAzMiBiaXQsIGJsb2NrIGJlbG93IG5vdCBuZWVkZWQKICAgICAgLyogRGVhbCB3aXRoICFAIyQlIDY0SyBsaW1pdDogKi8KICAgICAgLy9pZiAoc2l6ZW9mKGludCkgPD0gMikgewogICAgICAvLyAgICBpZiAobW9yZSA9PSAwICYmIHMtPnN0cnN0YXJ0ID09IDAgJiYgcy0+bG9va2FoZWFkID09IDApIHsKICAgICAgLy8gICAgICAgIG1vcmUgPSB3c2l6ZTsKICAgICAgLy8KICAgICAgLy8gIH0gZWxzZSBpZiAobW9yZSA9PSAodW5zaWduZWQpKC0xKSkgewogICAgICAvLyAgICAgICAgLyogVmVyeSB1bmxpa2VseSwgYnV0IHBvc3NpYmxlIG9uIDE2IGJpdCBtYWNoaW5lIGlmCiAgICAgIC8vICAgICAgICAgKiBzdHJzdGFydCA9PSAwICYmIGxvb2thaGVhZCA9PSAxIChpbnB1dCBkb25lIGEgYnl0ZSBhdCB0aW1lKQogICAgICAvLyAgICAgICAgICovCiAgICAgIC8vICAgICAgICBtb3JlLS07CiAgICAgIC8vICAgIH0KICAgICAgLy99CgogICAgICAvKiBJZiB0aGUgd2luZG93IGlzIGFsbW9zdCBmdWxsIGFuZCB0aGVyZSBpcyBpbnN1ZmZpY2llbnQgbG9va2FoZWFkLAogICAgICAgKiBtb3ZlIHRoZSB1cHBlciBoYWxmIHRvIHRoZSBsb3dlciBvbmUgdG8gbWFrZSByb29tIGluIHRoZSB1cHBlciBoYWxmLgogICAgICAgKi8KICAgICAgaWYgKHMuc3Ryc3RhcnQgPj0gX3dfc2l6ZSArIChfd19zaXplIC0gTUlOX0xPT0tBSEVBRCkpIHsKICAgICAgICBzLndpbmRvdy5zZXQocy53aW5kb3cuc3ViYXJyYXkoX3dfc2l6ZSwgX3dfc2l6ZSArIF93X3NpemUpLCAwKTsKICAgICAgICBzLm1hdGNoX3N0YXJ0IC09IF93X3NpemU7CiAgICAgICAgcy5zdHJzdGFydCAtPSBfd19zaXplOwogICAgICAgIC8qIHdlIG5vdyBoYXZlIHN0cnN0YXJ0ID49IE1BWF9ESVNUICovCiAgICAgICAgcy5ibG9ja19zdGFydCAtPSBfd19zaXplOwoKICAgICAgICAvKiBTbGlkZSB0aGUgaGFzaCB0YWJsZSAoY291bGQgYmUgYXZvaWRlZCB3aXRoIDMyIGJpdCB2YWx1ZXMKICAgICAgICAgYXQgdGhlIGV4cGVuc2Ugb2YgbWVtb3J5IHVzYWdlKS4gV2Ugc2xpZGUgZXZlbiB3aGVuIGxldmVsID09IDAKICAgICAgICAgdG8ga2VlcCB0aGUgaGFzaCB0YWJsZSBjb25zaXN0ZW50IGlmIHdlIHN3aXRjaCBiYWNrIHRvIGxldmVsID4gMAogICAgICAgICBsYXRlci4gKFVzaW5nIGxldmVsIDAgcGVybWFuZW50bHkgaXMgbm90IGFuIG9wdGltYWwgdXNhZ2Ugb2YKICAgICAgICAgemxpYiwgc28gd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGlzIHBhdGhvbG9naWNhbCBjYXNlLikKICAgICAgICAgKi8KCiAgICAgICAgbiA9IHMuaGFzaF9zaXplOwogICAgICAgIHAgPSBuOwogICAgICAgIGRvIHsKICAgICAgICAgIG0gPSBzLmhlYWRbLS1wXTsKICAgICAgICAgIHMuaGVhZFtwXSA9IG0gPj0gX3dfc2l6ZSA/IG0gLSBfd19zaXplIDogMDsKICAgICAgICB9IHdoaWxlICgtLW4pOwogICAgICAgIG4gPSBfd19zaXplOwogICAgICAgIHAgPSBuOwogICAgICAgIGRvIHsKICAgICAgICAgIG0gPSBzLnByZXZbLS1wXTsKICAgICAgICAgIHMucHJldltwXSA9IG0gPj0gX3dfc2l6ZSA/IG0gLSBfd19zaXplIDogMDsKICAgICAgICAgIC8qIElmIG4gaXMgbm90IG9uIGFueSBoYXNoIGNoYWluLCBwcmV2W25dIGlzIGdhcmJhZ2UgYnV0CiAgICAgICAgICAgKiBpdHMgdmFsdWUgd2lsbCBuZXZlciBiZSB1c2VkLgogICAgICAgICAgICovCiAgICAgICAgfSB3aGlsZSAoLS1uKTsKICAgICAgICBtb3JlICs9IF93X3NpemU7CiAgICAgIH0KICAgICAgaWYgKHMuc3RybS5hdmFpbF9pbiA9PT0gMCkgewogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgICAvKiBJZiB0aGVyZSB3YXMgbm8gc2xpZGluZzoKICAgICAgICogICAgc3Ryc3RhcnQgPD0gV1NJWkUrTUFYX0RJU1QtMSAmJiBsb29rYWhlYWQgPD0gTUlOX0xPT0tBSEVBRCAtIDEgJiYKICAgICAgICogICAgbW9yZSA9PSB3aW5kb3dfc2l6ZSAtIGxvb2thaGVhZCAtIHN0cnN0YXJ0CiAgICAgICAqID0+IG1vcmUgPj0gd2luZG93X3NpemUgLSAoTUlOX0xPT0tBSEVBRC0xICsgV1NJWkUgKyBNQVhfRElTVC0xKQogICAgICAgKiA9PiBtb3JlID49IHdpbmRvd19zaXplIC0gMipXU0laRSArIDIKICAgICAgICogSW4gdGhlIEJJR19NRU0gb3IgTU1BUCBjYXNlIChub3QgeWV0IHN1cHBvcnRlZCksCiAgICAgICAqICAgd2luZG93X3NpemUgPT0gaW5wdXRfc2l6ZSArIE1JTl9MT09LQUhFQUQgICYmCiAgICAgICAqICAgc3Ryc3RhcnQgKyBzLT5sb29rYWhlYWQgPD0gaW5wdXRfc2l6ZSA9PiBtb3JlID49IE1JTl9MT09LQUhFQUQuCiAgICAgICAqIE90aGVyd2lzZSwgd2luZG93X3NpemUgPT0gMipXU0laRSBzbyBtb3JlID49IDIuCiAgICAgICAqIElmIHRoZXJlIHdhcyBzbGlkaW5nLCBtb3JlID49IFdTSVpFLiBTbyBpbiBhbGwgY2FzZXMsIG1vcmUgPj0gMi4KICAgICAgICovCiAgICAgIC8vQXNzZXJ0KG1vcmUgPj0gMiwgIm1vcmUgPCAyIik7CiAgICAgIG4gPSByZWFkX2J1ZihzLnN0cm0sIHMud2luZG93LCBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQsIG1vcmUpOwogICAgICBzLmxvb2thaGVhZCArPSBuOwoKICAgICAgLyogSW5pdGlhbGl6ZSB0aGUgaGFzaCB2YWx1ZSBub3cgdGhhdCB3ZSBoYXZlIHNvbWUgaW5wdXQ6ICovCiAgICAgIGlmIChzLmxvb2thaGVhZCArIHMuaW5zZXJ0ID49IE1JTl9NQVRDSCkgewogICAgICAgIHN0ciA9IHMuc3Ryc3RhcnQgLSBzLmluc2VydDsKICAgICAgICBzLmluc19oID0gcy53aW5kb3dbc3RyXTsKCiAgICAgICAgLyogVVBEQVRFX0hBU0gocywgcy0+aW5zX2gsIHMtPndpbmRvd1tzdHIgKyAxXSk7ICovCiAgICAgICAgcy5pbnNfaCA9IEhBU0gocywgcy5pbnNfaCwgcy53aW5kb3dbc3RyICsgMV0pOwogICAgICAgIC8vI2lmIE1JTl9NQVRDSCAhPSAzCiAgICAgICAgLy8gICAgICAgIENhbGwgdXBkYXRlX2hhc2goKSBNSU5fTUFUQ0gtMyBtb3JlIHRpbWVzCiAgICAgICAgLy8jZW5kaWYKICAgICAgICB3aGlsZSAocy5pbnNlcnQpIHsKICAgICAgICAgIC8qIFVQREFURV9IQVNIKHMsIHMtPmluc19oLCBzLT53aW5kb3dbc3RyICsgTUlOX01BVENILTFdKTsgKi8KICAgICAgICAgIHMuaW5zX2ggPSBIQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3N0ciArIE1JTl9NQVRDSCAtIDFdKTsKICAgICAgICAgIHMucHJldltzdHIgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07CiAgICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzdHI7CiAgICAgICAgICBzdHIrKzsKICAgICAgICAgIHMuaW5zZXJ0LS07CiAgICAgICAgICBpZiAocy5sb29rYWhlYWQgKyBzLmluc2VydCA8IE1JTl9NQVRDSCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgLyogSWYgdGhlIHdob2xlIGlucHV0IGhhcyBsZXNzIHRoYW4gTUlOX01BVENIIGJ5dGVzLCBpbnNfaCBpcyBnYXJiYWdlLAogICAgICAgKiBidXQgdGhpcyBpcyBub3QgaW1wb3J0YW50IHNpbmNlIG9ubHkgbGl0ZXJhbCBieXRlcyB3aWxsIGJlIGVtaXR0ZWQuCiAgICAgICAqLwogICAgfSB3aGlsZSAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIHMuc3RybS5hdmFpbF9pbiAhPT0gMCk7CgogICAgLyogSWYgdGhlIFdJTl9JTklUIGJ5dGVzIGFmdGVyIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgZGF0YSBoYXZlIG5ldmVyIGJlZW4KICAgICAqIHdyaXR0ZW4sIHRoZW4gemVybyB0aG9zZSBieXRlcyBpbiBvcmRlciB0byBhdm9pZCBtZW1vcnkgY2hlY2sgcmVwb3J0cyBvZgogICAgICogdGhlIHVzZSBvZiB1bmluaXRpYWxpemVkIChvciB1bmluaXRpYWxpc2VkIGFzIEp1bGlhbiB3cml0ZXMpIGJ5dGVzIGJ5CiAgICAgKiB0aGUgbG9uZ2VzdCBtYXRjaCByb3V0aW5lcy4gIFVwZGF0ZSB0aGUgaGlnaCB3YXRlciBtYXJrIGZvciB0aGUgbmV4dAogICAgICogdGltZSB0aHJvdWdoIGhlcmUuICBXSU5fSU5JVCBpcyBzZXQgdG8gTUFYX01BVENIIHNpbmNlIHRoZSBsb25nZXN0IG1hdGNoCiAgICAgKiByb3V0aW5lcyBhbGxvdyBzY2FubmluZyB0byBzdHJzdGFydCArIE1BWF9NQVRDSCwgaWdub3JpbmcgbG9va2FoZWFkLgogICAgICovCiAgICAvLyAgaWYgKHMuaGlnaF93YXRlciA8IHMud2luZG93X3NpemUpIHsKICAgIC8vICAgIGNvbnN0IGN1cnIgPSBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQ7CiAgICAvLyAgICBsZXQgaW5pdCA9IDA7CiAgICAvLwogICAgLy8gICAgaWYgKHMuaGlnaF93YXRlciA8IGN1cnIpIHsKICAgIC8vICAgICAgLyogUHJldmlvdXMgaGlnaCB3YXRlciBtYXJrIGJlbG93IGN1cnJlbnQgZGF0YSAtLSB6ZXJvIFdJTl9JTklUCiAgICAvLyAgICAgICAqIGJ5dGVzIG9yIHVwIHRvIGVuZCBvZiB3aW5kb3csIHdoaWNoZXZlciBpcyBsZXNzLgogICAgLy8gICAgICAgKi8KICAgIC8vICAgICAgaW5pdCA9IHMud2luZG93X3NpemUgLSBjdXJyOwogICAgLy8gICAgICBpZiAoaW5pdCA+IFdJTl9JTklUKQogICAgLy8gICAgICAgIGluaXQgPSBXSU5fSU5JVDsKICAgIC8vICAgICAgem1lbXplcm8ocy0+d2luZG93ICsgY3VyciwgKHVuc2lnbmVkKWluaXQpOwogICAgLy8gICAgICBzLT5oaWdoX3dhdGVyID0gY3VyciArIGluaXQ7CiAgICAvLyAgICB9CiAgICAvLyAgICBlbHNlIGlmIChzLT5oaWdoX3dhdGVyIDwgKHVsZyljdXJyICsgV0lOX0lOSVQpIHsKICAgIC8vICAgICAgLyogSGlnaCB3YXRlciBtYXJrIGF0IG9yIGFib3ZlIGN1cnJlbnQgZGF0YSwgYnV0IGJlbG93IGN1cnJlbnQgZGF0YQogICAgLy8gICAgICAgKiBwbHVzIFdJTl9JTklUIC0tIHplcm8gb3V0IHRvIGN1cnJlbnQgZGF0YSBwbHVzIFdJTl9JTklULCBvciB1cAogICAgLy8gICAgICAgKiB0byBlbmQgb2Ygd2luZG93LCB3aGljaGV2ZXIgaXMgbGVzcy4KICAgIC8vICAgICAgICovCiAgICAvLyAgICAgIGluaXQgPSAodWxnKWN1cnIgKyBXSU5fSU5JVCAtIHMtPmhpZ2hfd2F0ZXI7CiAgICAvLyAgICAgIGlmIChpbml0ID4gcy0+d2luZG93X3NpemUgLSBzLT5oaWdoX3dhdGVyKQogICAgLy8gICAgICAgIGluaXQgPSBzLT53aW5kb3dfc2l6ZSAtIHMtPmhpZ2hfd2F0ZXI7CiAgICAvLyAgICAgIHptZW16ZXJvKHMtPndpbmRvdyArIHMtPmhpZ2hfd2F0ZXIsICh1bnNpZ25lZClpbml0KTsKICAgIC8vICAgICAgcy0+aGlnaF93YXRlciArPSBpbml0OwogICAgLy8gICAgfQogICAgLy8gIH0KICAgIC8vCiAgICAvLyAgQXNzZXJ0KCh1bGcpcy0+c3Ryc3RhcnQgPD0gcy0+d2luZG93X3NpemUgLSBNSU5fTE9PS0FIRUFELAogICAgLy8gICAgIm5vdCBlbm91Z2ggcm9vbSBmb3Igc2VhcmNoIik7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogQ29weSB3aXRob3V0IGNvbXByZXNzaW9uIGFzIG11Y2ggYXMgcG9zc2libGUgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLCByZXR1cm4KICAgKiB0aGUgY3VycmVudCBibG9jayBzdGF0ZS4KICAgKiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGluc2VydCBuZXcgc3RyaW5ncyBpbiB0aGUgZGljdGlvbmFyeSBzaW5jZQogICAqIHVuY29tcHJlc3NpYmxlIGRhdGEgaXMgcHJvYmFibHkgbm90IHVzZWZ1bC4gVGhpcyBmdW5jdGlvbiBpcyB1c2VkCiAgICogb25seSBmb3IgdGhlIGxldmVsPTAgY29tcHJlc3Npb24gb3B0aW9uLgogICAqIE5PVEU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIG9wdGltaXplZCB0byBhdm9pZCBleHRyYSBjb3B5aW5nIGZyb20KICAgKiB3aW5kb3cgdG8gcGVuZGluZ19idWYuCiAgICovCiAgdmFyIGRlZmxhdGVfc3RvcmVkID0gZnVuY3Rpb24gZGVmbGF0ZV9zdG9yZWQocywgZmx1c2gpIHsKICAgIC8qIFN0b3JlZCBibG9ja3MgYXJlIGxpbWl0ZWQgdG8gMHhmZmZmIGJ5dGVzLCBwZW5kaW5nX2J1ZiBpcyBsaW1pdGVkCiAgICAgKiB0byBwZW5kaW5nX2J1Zl9zaXplLCBhbmQgZWFjaCBzdG9yZWQgYmxvY2sgaGFzIGEgNSBieXRlIGhlYWRlcjoKICAgICAqLwogICAgdmFyIG1heF9ibG9ja19zaXplID0gMHhmZmZmOwogICAgaWYgKG1heF9ibG9ja19zaXplID4gcy5wZW5kaW5nX2J1Zl9zaXplIC0gNSkgewogICAgICBtYXhfYmxvY2tfc2l6ZSA9IHMucGVuZGluZ19idWZfc2l6ZSAtIDU7CiAgICB9CgogICAgLyogQ29weSBhcyBtdWNoIGFzIHBvc3NpYmxlIGZyb20gaW5wdXQgdG8gb3V0cHV0OiAqLwogICAgZm9yICg7OykgewogICAgICAvKiBGaWxsIHRoZSB3aW5kb3cgYXMgbXVjaCBhcyBwb3NzaWJsZTogKi8KICAgICAgaWYgKHMubG9va2FoZWFkIDw9IDEpIHsKICAgICAgICAvL0Fzc2VydChzLT5zdHJzdGFydCA8IHMtPndfc2l6ZStNQVhfRElTVChzKSB8fAogICAgICAgIC8vICBzLT5ibG9ja19zdGFydCA+PSAobG9uZylzLT53X3NpemUsICJzbGlkZSB0b28gbGF0ZSIpOwogICAgICAgIC8vICAgICAgaWYgKCEocy5zdHJzdGFydCA8IHMud19zaXplICsgKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkgfHwKICAgICAgICAvLyAgICAgICAgcy5ibG9ja19zdGFydCA+PSBzLndfc2l6ZSkpIHsKICAgICAgICAvLyAgICAgICAgdGhyb3cgIG5ldyBFcnJvcigic2xpZGUgdG9vIGxhdGUiKTsKICAgICAgICAvLyAgICAgIH0KCiAgICAgICAgZmlsbF93aW5kb3cocyk7CiAgICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwICYmIGZsdXNoID09PSBaX05PX0ZMVVNIJDIpIHsKICAgICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgICAgfQogICAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovCiAgICAgIH0KICAgICAgLy9Bc3NlcnQocy0+YmxvY2tfc3RhcnQgPj0gMEwsICJibG9jayBnb25lIik7CiAgICAgIC8vICAgIGlmIChzLmJsb2NrX3N0YXJ0IDwgMCkgdGhyb3cgbmV3IEVycm9yKCJibG9jayBnb25lIik7CgogICAgICBzLnN0cnN0YXJ0ICs9IHMubG9va2FoZWFkOwogICAgICBzLmxvb2thaGVhZCA9IDA7CgogICAgICAvKiBFbWl0IGEgc3RvcmVkIGJsb2NrIGlmIHBlbmRpbmdfYnVmIHdpbGwgYmUgZnVsbDogKi8KICAgICAgdmFyIG1heF9zdGFydCA9IHMuYmxvY2tfc3RhcnQgKyBtYXhfYmxvY2tfc2l6ZTsKICAgICAgaWYgKHMuc3Ryc3RhcnQgPT09IDAgfHwgcy5zdHJzdGFydCA+PSBtYXhfc3RhcnQpIHsKICAgICAgICAvKiBzdHJzdGFydCA9PSAwIGlzIHBvc3NpYmxlIHdoZW4gd3JhcGFyb3VuZCBvbiAxNi1iaXQgbWFjaGluZSAqLwogICAgICAgIHMubG9va2FoZWFkID0gcy5zdHJzdGFydCAtIG1heF9zdGFydDsKICAgICAgICBzLnN0cnN0YXJ0ID0gbWF4X3N0YXJ0OwogICAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi8KICAgICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTsKICAgICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTsKICAgICAgICB9CiAgICAgICAgLyoqKi8KICAgICAgfQogICAgICAvKiBGbHVzaCBpZiB3ZSBtYXkgaGF2ZSB0byBzbGlkZSwgb3RoZXJ3aXNlIGJsb2NrX3N0YXJ0IG1heSBiZWNvbWUKICAgICAgICogbmVnYXRpdmUgYW5kIHRoZSBkYXRhIHdpbGwgYmUgZ29uZToKICAgICAgICovCiAgICAgIGlmIChzLnN0cnN0YXJ0IC0gcy5ibG9ja19zdGFydCA+PSBzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpIHsKICAgICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovCiAgICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7CiAgICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHsKICAgICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgICAgfQogICAgICAgIC8qKiovCiAgICAgIH0KICAgIH0KICAgIHMuaW5zZXJ0ID0gMDsKICAgIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gkMykgewogICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovCiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7CiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7CiAgICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEOwogICAgICB9CiAgICAgIC8qKiovCiAgICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTsKICAgIH0KICAgIGlmIChzLnN0cnN0YXJ0ID4gcy5ibG9ja19zdGFydCkgewogICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovCiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgIH0KICAgICAgLyoqKi8KICAgIH0KICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogQ29tcHJlc3MgYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0sIHJldHVybiB0aGUgY3VycmVudAogICAqIGJsb2NrIHN0YXRlLgogICAqIFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgcGVyZm9ybSBsYXp5IGV2YWx1YXRpb24gb2YgbWF0Y2hlcyBhbmQgaW5zZXJ0cwogICAqIG5ldyBzdHJpbmdzIGluIHRoZSBkaWN0aW9uYXJ5IG9ubHkgZm9yIHVubWF0Y2hlZCBzdHJpbmdzIG9yIGZvciBzaG9ydAogICAqIG1hdGNoZXMuIEl0IGlzIHVzZWQgb25seSBmb3IgdGhlIGZhc3QgY29tcHJlc3Npb24gb3B0aW9ucy4KICAgKi8KICB2YXIgZGVmbGF0ZV9mYXN0ID0gZnVuY3Rpb24gZGVmbGF0ZV9mYXN0KHMsIGZsdXNoKSB7CiAgICB2YXIgaGFzaF9oZWFkOyAvKiBoZWFkIG9mIHRoZSBoYXNoIGNoYWluICovCiAgICB2YXIgYmZsdXNoOyAvKiBzZXQgaWYgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQgKi8KCiAgICBmb3IgKDs7KSB7CiAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGFsd2F5cyBoYXZlIGVub3VnaCBsb29rYWhlYWQsIGV4Y2VwdAogICAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlcwogICAgICAgKiBmb3IgdGhlIG5leHQgbWF0Y2gsIHBsdXMgTUlOX01BVENIIGJ5dGVzIHRvIGluc2VydCB0aGUKICAgICAgICogc3RyaW5nIGZvbGxvd2luZyB0aGUgbmV4dCBtYXRjaC4KICAgICAgICovCiAgICAgIGlmIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQpIHsKICAgICAgICBmaWxsX3dpbmRvdyhzKTsKICAgICAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIGZsdXNoID09PSBaX05PX0ZMVVNIJDIpIHsKICAgICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgICAgfQogICAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgewogICAgICAgICAgYnJlYWs7IC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovCiAgICAgICAgfQogICAgICB9CgogICAgICAvKiBJbnNlcnQgdGhlIHN0cmluZyB3aW5kb3dbc3Ryc3RhcnQgLi4gc3Ryc3RhcnQrMl0gaW4gdGhlCiAgICAgICAqIGRpY3Rpb25hcnksIGFuZCBzZXQgaGFzaF9oZWFkIHRvIHRoZSBoZWFkIG9mIHRoZSBoYXNoIGNoYWluOgogICAgICAgKi8KICAgICAgaGFzaF9oZWFkID0gMCAvKk5JTCovOwogICAgICBpZiAocy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7CiAgICAgICAgLyoqKiBJTlNFUlRfU1RSSU5HKHMsIHMuc3Ryc3RhcnQsIGhhc2hfaGVhZCk7ICoqKi8KICAgICAgICBzLmluc19oID0gSEFTSChzLCBzLmluc19oLCBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgTUlOX01BVENIIC0gMV0pOwogICAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdOwogICAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7CiAgICAgICAgLyoqKi8KICAgICAgfQoKICAgICAgLyogRmluZCB0aGUgbG9uZ2VzdCBtYXRjaCwgZGlzY2FyZGluZyB0aG9zZSA8PSBwcmV2X2xlbmd0aC4KICAgICAgICogQXQgdGhpcyBwb2ludCB3ZSBoYXZlIGFsd2F5cyBtYXRjaF9sZW5ndGggPCBNSU5fTUFUQ0gKICAgICAgICovCiAgICAgIGlmIChoYXNoX2hlYWQgIT09IDAgLypOSUwqLyAmJiBzLnN0cnN0YXJ0IC0gaGFzaF9oZWFkIDw9IHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkgewogICAgICAgIC8qIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLCB3ZSBwcmV2ZW50IG1hdGNoZXMgd2l0aCB0aGUgc3RyaW5nCiAgICAgICAgICogb2Ygd2luZG93IGluZGV4IDAgKGluIHBhcnRpY3VsYXIgd2UgaGF2ZSB0byBhdm9pZCBhIG1hdGNoCiAgICAgICAgICogb2YgdGhlIHN0cmluZyB3aXRoIGl0c2VsZiBhdCB0aGUgc3RhcnQgb2YgdGhlIGlucHV0IGZpbGUpLgogICAgICAgICAqLwogICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gbG9uZ2VzdF9tYXRjaChzLCBoYXNoX2hlYWQpOwogICAgICAgIC8qIGxvbmdlc3RfbWF0Y2goKSBzZXRzIG1hdGNoX3N0YXJ0ICovCiAgICAgIH0KICAgICAgaWYgKHMubWF0Y2hfbGVuZ3RoID49IE1JTl9NQVRDSCkgewogICAgICAgIC8vIGNoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQsIHMubWF0Y2hfc3RhcnQsIHMubWF0Y2hfbGVuZ3RoKTsgLy8gZm9yIGRlYnVnIG9ubHkKCiAgICAgICAgLyoqKiBfdHJfdGFsbHlfZGlzdChzLCBzLnN0cnN0YXJ0IC0gcy5tYXRjaF9zdGFydCwKICAgICAgICAgICAgICAgICAgICAgICBzLm1hdGNoX2xlbmd0aCAtIE1JTl9NQVRDSCwgYmZsdXNoKTsgKioqLwogICAgICAgIGJmbHVzaCA9IF90cl90YWxseShzLCBzLnN0cnN0YXJ0IC0gcy5tYXRjaF9zdGFydCwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gpOwogICAgICAgIHMubG9va2FoZWFkIC09IHMubWF0Y2hfbGVuZ3RoOwoKICAgICAgICAvKiBJbnNlcnQgbmV3IHN0cmluZ3MgaW4gdGhlIGhhc2ggdGFibGUgb25seSBpZiB0aGUgbWF0Y2ggbGVuZ3RoCiAgICAgICAgICogaXMgbm90IHRvbyBsYXJnZS4gVGhpcyBzYXZlcyB0aW1lIGJ1dCBkZWdyYWRlcyBjb21wcmVzc2lvbi4KICAgICAgICAgKi8KICAgICAgICBpZiAocy5tYXRjaF9sZW5ndGggPD0gcy5tYXhfbGF6eV9tYXRjaCAvKm1heF9pbnNlcnRfbGVuZ3RoKi8gJiYgcy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7CiAgICAgICAgICBzLm1hdGNoX2xlbmd0aC0tOyAvKiBzdHJpbmcgYXQgc3Ryc3RhcnQgYWxyZWFkeSBpbiB0YWJsZSAqLwogICAgICAgICAgZG8gewogICAgICAgICAgICBzLnN0cnN0YXJ0Kys7CiAgICAgICAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovCiAgICAgICAgICAgIHMuaW5zX2ggPSBIQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3Muc3Ryc3RhcnQgKyBNSU5fTUFUQ0ggLSAxXSk7CiAgICAgICAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdOwogICAgICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0OwogICAgICAgICAgICAvKioqLwogICAgICAgICAgICAvKiBzdHJzdGFydCBuZXZlciBleGNlZWRzIFdTSVpFLU1BWF9NQVRDSCwgc28gdGhlcmUgYXJlCiAgICAgICAgICAgICAqIGFsd2F5cyBNSU5fTUFUQ0ggYnl0ZXMgYWhlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgfSB3aGlsZSAoLS1zLm1hdGNoX2xlbmd0aCAhPT0gMCk7CiAgICAgICAgICBzLnN0cnN0YXJ0Kys7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHMuc3Ryc3RhcnQgKz0gcy5tYXRjaF9sZW5ndGg7CiAgICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IDA7CiAgICAgICAgICBzLmluc19oID0gcy53aW5kb3dbcy5zdHJzdGFydF07CiAgICAgICAgICAvKiBVUERBVEVfSEFTSChzLCBzLmluc19oLCBzLndpbmRvd1tzLnN0cnN0YXJ0KzFdKTsgKi8KICAgICAgICAgIHMuaW5zX2ggPSBIQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3Muc3Ryc3RhcnQgKyAxXSk7CgogICAgICAgICAgLy8jaWYgTUlOX01BVENIICE9IDMKICAgICAgICAgIC8vICAgICAgICAgICAgICAgIENhbGwgVVBEQVRFX0hBU0goKSBNSU5fTUFUQ0gtMyBtb3JlIHRpbWVzCiAgICAgICAgICAvLyNlbmRpZgogICAgICAgICAgLyogSWYgbG9va2FoZWFkIDwgTUlOX01BVENILCBpbnNfaCBpcyBnYXJiYWdlLCBidXQgaXQgZG9lcyBub3QKICAgICAgICAgICAqIG1hdHRlciBzaW5jZSBpdCB3aWxsIGJlIHJlY29tcHV0ZWQgYXQgbmV4dCBkZWZsYXRlIGNhbGwuCiAgICAgICAgICAgKi8KICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLyogTm8gbWF0Y2gsIG91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqLwogICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCIlYyIsIHMud2luZG93W3Muc3Ryc3RhcnRdKSk7CiAgICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnRdLCBiZmx1c2gpOyAqKiovCiAgICAgICAgYmZsdXNoID0gX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnRdKTsKICAgICAgICBzLmxvb2thaGVhZC0tOwogICAgICAgIHMuc3Ryc3RhcnQrKzsKICAgICAgfQogICAgICBpZiAoYmZsdXNoKSB7CiAgICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqLwogICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7CiAgICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFOwogICAgICAgIH0KICAgICAgICAvKioqLwogICAgICB9CiAgICB9CiAgICBzLmluc2VydCA9IHMuc3Ryc3RhcnQgPCBNSU5fTUFUQ0ggLSAxID8gcy5zdHJzdGFydCA6IE1JTl9NQVRDSCAtIDE7CiAgICBpZiAoZmx1c2ggPT09IFpfRklOSVNIJDMpIHsKICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqLwogICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpOwogICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDsKICAgICAgfQogICAgICAvKioqLwogICAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7CiAgICB9CiAgICBpZiAocy5sYXN0X2xpdCkgewogICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovCiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgIH0KICAgICAgLyoqKi8KICAgIH0KICAgIHJldHVybiBCU19CTE9DS19ET05FOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIFNhbWUgYXMgYWJvdmUsIGJ1dCBhY2hpZXZlcyBiZXR0ZXIgY29tcHJlc3Npb24uIFdlIHVzZSBhIGxhenkKICAgKiBldmFsdWF0aW9uIGZvciBtYXRjaGVzOiBhIG1hdGNoIGlzIGZpbmFsbHkgYWRvcHRlZCBvbmx5IGlmIHRoZXJlIGlzCiAgICogbm8gYmV0dGVyIG1hdGNoIGF0IHRoZSBuZXh0IHdpbmRvdyBwb3NpdGlvbi4KICAgKi8KICB2YXIgZGVmbGF0ZV9zbG93ID0gZnVuY3Rpb24gZGVmbGF0ZV9zbG93KHMsIGZsdXNoKSB7CiAgICB2YXIgaGFzaF9oZWFkOyAvKiBoZWFkIG9mIGhhc2ggY2hhaW4gKi8KICAgIHZhciBiZmx1c2g7IC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqLwoKICAgIHZhciBtYXhfaW5zZXJ0OwoKICAgIC8qIFByb2Nlc3MgdGhlIGlucHV0IGJsb2NrLiAqLwogICAgZm9yICg7OykgewogICAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHQKICAgICAgICogYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQgZmlsZS4gV2UgbmVlZCBNQVhfTUFUQ0ggYnl0ZXMKICAgICAgICogZm9yIHRoZSBuZXh0IG1hdGNoLCBwbHVzIE1JTl9NQVRDSCBieXRlcyB0byBpbnNlcnQgdGhlCiAgICAgICAqIHN0cmluZyBmb2xsb3dpbmcgdGhlIG5leHQgbWF0Y2guCiAgICAgICAqLwogICAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEKSB7CiAgICAgICAgZmlsbF93aW5kb3cocyk7CiAgICAgICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCAmJiBmbHVzaCA9PT0gWl9OT19GTFVTSCQyKSB7CiAgICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFOwogICAgICAgIH0KICAgICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0gLyogZmx1c2ggdGhlIGN1cnJlbnQgYmxvY2sgKi8KICAgICAgfQoKICAgICAgLyogSW5zZXJ0IHRoZSBzdHJpbmcgd2luZG93W3N0cnN0YXJ0IC4uIHN0cnN0YXJ0KzJdIGluIHRoZQogICAgICAgKiBkaWN0aW9uYXJ5LCBhbmQgc2V0IGhhc2hfaGVhZCB0byB0aGUgaGVhZCBvZiB0aGUgaGFzaCBjaGFpbjoKICAgICAgICovCiAgICAgIGhhc2hfaGVhZCA9IDAgLypOSUwqLzsKICAgICAgaWYgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkgewogICAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovCiAgICAgICAgcy5pbnNfaCA9IEhBU0gocywgcy5pbnNfaCwgcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKTsKICAgICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTsKICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0OwogICAgICAgIC8qKiovCiAgICAgIH0KCiAgICAgIC8qIEZpbmQgdGhlIGxvbmdlc3QgbWF0Y2gsIGRpc2NhcmRpbmcgdGhvc2UgPD0gcHJldl9sZW5ndGguCiAgICAgICAqLwogICAgICBzLnByZXZfbGVuZ3RoID0gcy5tYXRjaF9sZW5ndGg7CiAgICAgIHMucHJldl9tYXRjaCA9IHMubWF0Y2hfc3RhcnQ7CiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gTUlOX01BVENIIC0gMTsKICAgICAgaWYgKGhhc2hfaGVhZCAhPT0gMCAvKk5JTCovICYmIHMucHJldl9sZW5ndGggPCBzLm1heF9sYXp5X21hdGNoICYmIHMuc3Ryc3RhcnQgLSBoYXNoX2hlYWQgPD0gcy53X3NpemUgLSBNSU5fTE9PS0FIRUFEIC8qTUFYX0RJU1QocykqLykgewogICAgICAgIC8qIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLCB3ZSBwcmV2ZW50IG1hdGNoZXMgd2l0aCB0aGUgc3RyaW5nCiAgICAgICAgICogb2Ygd2luZG93IGluZGV4IDAgKGluIHBhcnRpY3VsYXIgd2UgaGF2ZSB0byBhdm9pZCBhIG1hdGNoCiAgICAgICAgICogb2YgdGhlIHN0cmluZyB3aXRoIGl0c2VsZiBhdCB0aGUgc3RhcnQgb2YgdGhlIGlucHV0IGZpbGUpLgogICAgICAgICAqLwogICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gbG9uZ2VzdF9tYXRjaChzLCBoYXNoX2hlYWQpOwogICAgICAgIC8qIGxvbmdlc3RfbWF0Y2goKSBzZXRzIG1hdGNoX3N0YXJ0ICovCgogICAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA8PSA1ICYmIChzLnN0cmF0ZWd5ID09PSBaX0ZJTFRFUkVEIHx8IHMubWF0Y2hfbGVuZ3RoID09PSBNSU5fTUFUQ0ggJiYgcy5zdHJzdGFydCAtIHMubWF0Y2hfc3RhcnQgPiA0MDk2IC8qVE9PX0ZBUiovKSkgewogICAgICAgICAgLyogSWYgcHJldl9tYXRjaCBpcyBhbHNvIE1JTl9NQVRDSCwgbWF0Y2hfc3RhcnQgaXMgZ2FyYmFnZQogICAgICAgICAgICogYnV0IHdlIHdpbGwgaWdub3JlIHRoZSBjdXJyZW50IG1hdGNoIGFueXdheS4KICAgICAgICAgICAqLwogICAgICAgICAgcy5tYXRjaF9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxOwogICAgICAgIH0KICAgICAgfQogICAgICAvKiBJZiB0aGVyZSB3YXMgYSBtYXRjaCBhdCB0aGUgcHJldmlvdXMgc3RlcCBhbmQgdGhlIGN1cnJlbnQKICAgICAgICogbWF0Y2ggaXMgbm90IGJldHRlciwgb3V0cHV0IHRoZSBwcmV2aW91cyBtYXRjaDoKICAgICAgICovCiAgICAgIGlmIChzLnByZXZfbGVuZ3RoID49IE1JTl9NQVRDSCAmJiBzLm1hdGNoX2xlbmd0aCA8PSBzLnByZXZfbGVuZ3RoKSB7CiAgICAgICAgbWF4X2luc2VydCA9IHMuc3Ryc3RhcnQgKyBzLmxvb2thaGVhZCAtIE1JTl9NQVRDSDsKICAgICAgICAvKiBEbyBub3QgaW5zZXJ0IHN0cmluZ3MgaW4gaGFzaCB0YWJsZSBiZXlvbmQgdGhpcy4gKi8KCiAgICAgICAgLy9jaGVja19tYXRjaChzLCBzLnN0cnN0YXJ0LTEsIHMucHJldl9tYXRjaCwgcy5wcmV2X2xlbmd0aCk7CgogICAgICAgIC8qKipfdHJfdGFsbHlfZGlzdChzLCBzLnN0cnN0YXJ0IC0gMSAtIHMucHJldl9tYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICBzLnByZXZfbGVuZ3RoIC0gTUlOX01BVENILCBiZmx1c2gpOyoqKi8KICAgICAgICBiZmx1c2ggPSBfdHJfdGFsbHkocywgcy5zdHJzdGFydCAtIDEgLSBzLnByZXZfbWF0Y2gsIHMucHJldl9sZW5ndGggLSBNSU5fTUFUQ0gpOwogICAgICAgIC8qIEluc2VydCBpbiBoYXNoIHRhYmxlIGFsbCBzdHJpbmdzIHVwIHRvIHRoZSBlbmQgb2YgdGhlIG1hdGNoLgogICAgICAgICAqIHN0cnN0YXJ0LTEgYW5kIHN0cnN0YXJ0IGFyZSBhbHJlYWR5IGluc2VydGVkLiBJZiB0aGVyZSBpcyBub3QKICAgICAgICAgKiBlbm91Z2ggbG9va2FoZWFkLCB0aGUgbGFzdCB0d28gc3RyaW5ncyBhcmUgbm90IGluc2VydGVkIGluCiAgICAgICAgICogdGhlIGhhc2ggdGFibGUuCiAgICAgICAgICovCiAgICAgICAgcy5sb29rYWhlYWQgLT0gcy5wcmV2X2xlbmd0aCAtIDE7CiAgICAgICAgcy5wcmV2X2xlbmd0aCAtPSAyOwogICAgICAgIGRvIHsKICAgICAgICAgIGlmICgrK3Muc3Ryc3RhcnQgPD0gbWF4X2luc2VydCkgewogICAgICAgICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqLwogICAgICAgICAgICBzLmluc19oID0gSEFTSChzLCBzLmluc19oLCBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgTUlOX01BVENIIC0gMV0pOwogICAgICAgICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTsKICAgICAgICAgICAgcy5oZWFkW3MuaW5zX2hdID0gcy5zdHJzdGFydDsKICAgICAgICAgICAgLyoqKi8KICAgICAgICAgIH0KICAgICAgICB9IHdoaWxlICgtLXMucHJldl9sZW5ndGggIT09IDApOwogICAgICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMDsKICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7CiAgICAgICAgcy5zdHJzdGFydCsrOwogICAgICAgIGlmIChiZmx1c2gpIHsKICAgICAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi8KICAgICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTsKICAgICAgICAgIH0KICAgICAgICAgIC8qKiovCiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHMubWF0Y2hfYXZhaWxhYmxlKSB7CiAgICAgICAgLyogSWYgdGhlcmUgd2FzIG5vIG1hdGNoIGF0IHRoZSBwcmV2aW91cyBwb3NpdGlvbiwgb3V0cHV0IGEKICAgICAgICAgKiBzaW5nbGUgbGl0ZXJhbC4gSWYgdGhlcmUgd2FzIGEgbWF0Y2ggYnV0IHRoZSBjdXJyZW50IG1hdGNoCiAgICAgICAgICogaXMgbG9uZ2VyLCB0cnVuY2F0ZSB0aGUgcHJldmlvdXMgbWF0Y2ggdG8gYSBzaW5nbGUgbGl0ZXJhbC4KICAgICAgICAgKi8KICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwiJWMiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnQtMV0pKTsKICAgICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydC0xXSwgYmZsdXNoKTsgKioqLwogICAgICAgIGJmbHVzaCA9IF90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0IC0gMV0pOwogICAgICAgIGlmIChiZmx1c2gpIHsKICAgICAgICAgIC8qKiogRkxVU0hfQkxPQ0tfT05MWShzLCAwKSAqKiovCiAgICAgICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTsKICAgICAgICAgIC8qKiovCiAgICAgICAgfQogICAgICAgIHMuc3Ryc3RhcnQrKzsKICAgICAgICBzLmxvb2thaGVhZC0tOwogICAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7CiAgICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBUaGVyZSBpcyBubyBwcmV2aW91cyBtYXRjaCB0byBjb21wYXJlIHdpdGgsIHdhaXQgZm9yCiAgICAgICAgICogdGhlIG5leHQgc3RlcCB0byBkZWNpZGUuCiAgICAgICAgICovCiAgICAgICAgcy5tYXRjaF9hdmFpbGFibGUgPSAxOwogICAgICAgIHMuc3Ryc3RhcnQrKzsKICAgICAgICBzLmxvb2thaGVhZC0tOwogICAgICB9CiAgICB9CiAgICAvL0Fzc2VydCAoZmx1c2ggIT0gWl9OT19GTFVTSCwgIm5vIGZsdXNoPyIpOwogICAgaWYgKHMubWF0Y2hfYXZhaWxhYmxlKSB7CiAgICAgIC8vVHJhY2V2digoc3RkZXJyLCIlYyIsIHMtPndpbmRvd1tzLT5zdHJzdGFydC0xXSkpOwogICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydC0xXSwgYmZsdXNoKTsgKioqLwogICAgICBiZmx1c2ggPSBfdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydCAtIDFdKTsKICAgICAgcy5tYXRjaF9hdmFpbGFibGUgPSAwOwogICAgfQogICAgcy5pbnNlcnQgPSBzLnN0cnN0YXJ0IDwgTUlOX01BVENIIC0gMSA/IHMuc3Ryc3RhcnQgOiBNSU5fTUFUQ0ggLSAxOwogICAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCQzKSB7CiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMSk7ICoqKi8KICAgICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTsKICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHsKICAgICAgICByZXR1cm4gQlNfRklOSVNIX1NUQVJURUQ7CiAgICAgIH0KICAgICAgLyoqKi8KICAgICAgcmV0dXJuIEJTX0ZJTklTSF9ET05FOwogICAgfQogICAgaWYgKHMubGFzdF9saXQpIHsKICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqLwogICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTsKICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHsKICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFOwogICAgICB9CiAgICAgIC8qKiovCiAgICB9CiAgICByZXR1cm4gQlNfQkxPQ0tfRE9ORTsKICB9OwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgKiBGb3IgWl9STEUsIHNpbXBseSBsb29rIGZvciBydW5zIG9mIGJ5dGVzLCBnZW5lcmF0ZSBtYXRjaGVzIG9ubHkgb2YgZGlzdGFuY2UKICAgKiBvbmUuICBEbyBub3QgbWFpbnRhaW4gYSBoYXNoIHRhYmxlLiAgKEl0IHdpbGwgYmUgcmVnZW5lcmF0ZWQgaWYgdGhpcyBydW4gb2YKICAgKiBkZWZsYXRlIHN3aXRjaGVzIGF3YXkgZnJvbSBaX1JMRS4pCiAgICovCiAgdmFyIGRlZmxhdGVfcmxlID0gZnVuY3Rpb24gZGVmbGF0ZV9ybGUocywgZmx1c2gpIHsKICAgIHZhciBiZmx1c2g7IC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqLwogICAgdmFyIHByZXY7IC8qIGJ5dGUgYXQgZGlzdGFuY2Ugb25lIHRvIG1hdGNoICovCiAgICB2YXIgc2Nhbiwgc3RyZW5kOyAvKiBzY2FuIGdvZXMgdXAgdG8gc3RyZW5kIGZvciBsZW5ndGggb2YgcnVuICovCgogICAgdmFyIF93aW4gPSBzLndpbmRvdzsKICAgIGZvciAoOzspIHsKICAgICAgLyogTWFrZSBzdXJlIHRoYXQgd2UgYWx3YXlzIGhhdmUgZW5vdWdoIGxvb2thaGVhZCwgZXhjZXB0CiAgICAgICAqIGF0IHRoZSBlbmQgb2YgdGhlIGlucHV0IGZpbGUuIFdlIG5lZWQgTUFYX01BVENIIGJ5dGVzCiAgICAgICAqIGZvciB0aGUgbG9uZ2VzdCBydW4sIHBsdXMgb25lIGZvciB0aGUgdW5yb2xsZWQgbG9vcC4KICAgICAgICovCiAgICAgIGlmIChzLmxvb2thaGVhZCA8PSBNQVhfTUFUQ0gpIHsKICAgICAgICBmaWxsX3dpbmRvdyhzKTsKICAgICAgICBpZiAocy5sb29rYWhlYWQgPD0gTUFYX01BVENIICYmIGZsdXNoID09PSBaX05PX0ZMVVNIJDIpIHsKICAgICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgICAgfQogICAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfSAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqLwogICAgICB9CgogICAgICAvKiBTZWUgaG93IG1hbnkgdGltZXMgdGhlIHByZXZpb3VzIGJ5dGUgcmVwZWF0cyAqLwogICAgICBzLm1hdGNoX2xlbmd0aCA9IDA7CiAgICAgIGlmIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0ggJiYgcy5zdHJzdGFydCA+IDApIHsKICAgICAgICBzY2FuID0gcy5zdHJzdGFydCAtIDE7CiAgICAgICAgcHJldiA9IF93aW5bc2Nhbl07CiAgICAgICAgaWYgKHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dKSB7CiAgICAgICAgICBzdHJlbmQgPSBzLnN0cnN0YXJ0ICsgTUFYX01BVENIOwogICAgICAgICAgZG8gewogICAgICAgICAgICAvKmpzaGludCBub2VtcHR5OmZhbHNlKi8KICAgICAgICAgIH0gd2hpbGUgKHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgc2NhbiA8IHN0cmVuZCk7CiAgICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IE1BWF9NQVRDSCAtIChzdHJlbmQgLSBzY2FuKTsKICAgICAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+IHMubG9va2FoZWFkKSB7CiAgICAgICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gcy5sb29rYWhlYWQ7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vQXNzZXJ0KHNjYW4gPD0gcy0+d2luZG93Kyh1SW50KShzLT53aW5kb3dfc2l6ZS0xKSwgIndpbGQgc2NhbiIpOwogICAgICB9CgogICAgICAvKiBFbWl0IG1hdGNoIGlmIGhhdmUgcnVuIG9mIE1JTl9NQVRDSCBvciBsb25nZXIsIGVsc2UgZW1pdCBsaXRlcmFsICovCiAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+PSBNSU5fTUFUQ0gpIHsKICAgICAgICAvL2NoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQsIHMuc3Ryc3RhcnQgLSAxLCBzLm1hdGNoX2xlbmd0aCk7CgogICAgICAgIC8qKiogX3RyX3RhbGx5X2Rpc3QocywgMSwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gsIGJmbHVzaCk7ICoqKi8KICAgICAgICBiZmx1c2ggPSBfdHJfdGFsbHkocywgMSwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gpOwogICAgICAgIHMubG9va2FoZWFkIC09IHMubWF0Y2hfbGVuZ3RoOwogICAgICAgIHMuc3Ryc3RhcnQgKz0gcy5tYXRjaF9sZW5ndGg7CiAgICAgICAgcy5tYXRjaF9sZW5ndGggPSAwOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIE5vIG1hdGNoLCBvdXRwdXQgYSBsaXRlcmFsIGJ5dGUgKi8KICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwiJWMiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnRdKSk7CiAgICAgICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnRdLCBiZmx1c2gpOyAqKiovCiAgICAgICAgYmZsdXNoID0gX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnRdKTsKICAgICAgICBzLmxvb2thaGVhZC0tOwogICAgICAgIHMuc3Ryc3RhcnQrKzsKICAgICAgfQogICAgICBpZiAoYmZsdXNoKSB7CiAgICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqLwogICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7CiAgICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFOwogICAgICAgIH0KICAgICAgICAvKioqLwogICAgICB9CiAgICB9CiAgICBzLmluc2VydCA9IDA7CiAgICBpZiAoZmx1c2ggPT09IFpfRklOSVNIJDMpIHsKICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqLwogICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpOwogICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDsKICAgICAgfQogICAgICAvKioqLwogICAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7CiAgICB9CiAgICBpZiAocy5sYXN0X2xpdCkgewogICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovCiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgIH0KICAgICAgLyoqKi8KICAgIH0KICAgIHJldHVybiBCU19CTE9DS19ET05FOwogIH07CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIEZvciBaX0hVRkZNQU5fT05MWSwgZG8gbm90IGxvb2sgZm9yIG1hdGNoZXMuICBEbyBub3QgbWFpbnRhaW4gYSBoYXNoIHRhYmxlLgogICAqIChJdCB3aWxsIGJlIHJlZ2VuZXJhdGVkIGlmIHRoaXMgcnVuIG9mIGRlZmxhdGUgc3dpdGNoZXMgYXdheSBmcm9tIEh1ZmZtYW4uKQogICAqLwogIHZhciBkZWZsYXRlX2h1ZmYgPSBmdW5jdGlvbiBkZWZsYXRlX2h1ZmYocywgZmx1c2gpIHsKICAgIHZhciBiZmx1c2g7IC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqLwoKICAgIGZvciAoOzspIHsKICAgICAgLyogTWFrZSBzdXJlIHRoYXQgd2UgaGF2ZSBhIGxpdGVyYWwgdG8gd3JpdGUuICovCiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgewogICAgICAgIGZpbGxfd2luZG93KHMpOwogICAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgewogICAgICAgICAgaWYgKGZsdXNoID09PSBaX05PX0ZMVVNIJDIpIHsKICAgICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOyAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqLwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogT3V0cHV0IGEgbGl0ZXJhbCBieXRlICovCiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gMDsKICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIiVjIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0XSkpOwogICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi8KICAgICAgYmZsdXNoID0gX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnRdKTsKICAgICAgcy5sb29rYWhlYWQtLTsKICAgICAgcy5zdHJzdGFydCsrOwogICAgICBpZiAoYmZsdXNoKSB7CiAgICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqLwogICAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7CiAgICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFOwogICAgICAgIH0KICAgICAgICAvKioqLwogICAgICB9CiAgICB9CiAgICBzLmluc2VydCA9IDA7CiAgICBpZiAoZmx1c2ggPT09IFpfRklOSVNIJDMpIHsKICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqLwogICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIHRydWUpOwogICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDsKICAgICAgfQogICAgICAvKioqLwogICAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7CiAgICB9CiAgICBpZiAocy5sYXN0X2xpdCkgewogICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovCiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpOwogICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7CiAgICAgIH0KICAgICAgLyoqKi8KICAgIH0KICAgIHJldHVybiBCU19CTE9DS19ET05FOwogIH07CgogIC8qIFZhbHVlcyBmb3IgbWF4X2xhenlfbWF0Y2gsIGdvb2RfbWF0Y2ggYW5kIG1heF9jaGFpbl9sZW5ndGgsIGRlcGVuZGluZyBvbgogICAqIHRoZSBkZXNpcmVkIHBhY2sgbGV2ZWwgKDAuLjkpLiBUaGUgdmFsdWVzIGdpdmVuIGJlbG93IGhhdmUgYmVlbiB0dW5lZCB0bwogICAqIGV4Y2x1ZGUgd29yc3QgY2FzZSBwZXJmb3JtYW5jZSBmb3IgcGF0aG9sb2dpY2FsIGZpbGVzLiBCZXR0ZXIgdmFsdWVzIG1heSBiZQogICAqIGZvdW5kIGZvciBzcGVjaWZpYyBmaWxlcy4KICAgKi8KICBmdW5jdGlvbiBDb25maWcoZ29vZF9sZW5ndGgsIG1heF9sYXp5LCBuaWNlX2xlbmd0aCwgbWF4X2NoYWluLCBmdW5jKSB7CiAgICB0aGlzLmdvb2RfbGVuZ3RoID0gZ29vZF9sZW5ndGg7CiAgICB0aGlzLm1heF9sYXp5ID0gbWF4X2xhenk7CiAgICB0aGlzLm5pY2VfbGVuZ3RoID0gbmljZV9sZW5ndGg7CiAgICB0aGlzLm1heF9jaGFpbiA9IG1heF9jaGFpbjsKICAgIHRoaXMuZnVuYyA9IGZ1bmM7CiAgfQogIHZhciBjb25maWd1cmF0aW9uX3RhYmxlID0gWy8qICAgICAgZ29vZCBsYXp5IG5pY2UgY2hhaW4gKi8KICBuZXcgQ29uZmlnKDAsIDAsIDAsIDAsIGRlZmxhdGVfc3RvcmVkKSwgLyogMCBzdG9yZSBvbmx5ICovCiAgbmV3IENvbmZpZyg0LCA0LCA4LCA0LCBkZWZsYXRlX2Zhc3QpLCAvKiAxIG1heCBzcGVlZCwgbm8gbGF6eSBtYXRjaGVzICovCiAgbmV3IENvbmZpZyg0LCA1LCAxNiwgOCwgZGVmbGF0ZV9mYXN0KSwgLyogMiAqLwogIG5ldyBDb25maWcoNCwgNiwgMzIsIDMyLCBkZWZsYXRlX2Zhc3QpLCAvKiAzICovCgogIG5ldyBDb25maWcoNCwgNCwgMTYsIDE2LCBkZWZsYXRlX3Nsb3cpLCAvKiA0IGxhenkgbWF0Y2hlcyAqLwogIG5ldyBDb25maWcoOCwgMTYsIDMyLCAzMiwgZGVmbGF0ZV9zbG93KSwgLyogNSAqLwogIG5ldyBDb25maWcoOCwgMTYsIDEyOCwgMTI4LCBkZWZsYXRlX3Nsb3cpLCAvKiA2ICovCiAgbmV3IENvbmZpZyg4LCAzMiwgMTI4LCAyNTYsIGRlZmxhdGVfc2xvdyksIC8qIDcgKi8KICBuZXcgQ29uZmlnKDMyLCAxMjgsIDI1OCwgMTAyNCwgZGVmbGF0ZV9zbG93KSwgLyogOCAqLwogIG5ldyBDb25maWcoMzIsIDI1OCwgMjU4LCA0MDk2LCBkZWZsYXRlX3Nsb3cpIC8qIDkgbWF4IGNvbXByZXNzaW9uICovXTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICogSW5pdGlhbGl6ZSB0aGUgImxvbmdlc3QgbWF0Y2giIHJvdXRpbmVzIGZvciBhIG5ldyB6bGliIHN0cmVhbQogICAqLwogIHZhciBsbV9pbml0ID0gZnVuY3Rpb24gbG1faW5pdChzKSB7CiAgICBzLndpbmRvd19zaXplID0gMiAqIHMud19zaXplOwoKICAgIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqLwogICAgemVybyhzLmhlYWQpOyAvLyBGaWxsIHdpdGggTklMICg9IDApOwoKICAgIC8qIFNldCB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnM6CiAgICAgKi8KICAgIHMubWF4X2xhenlfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9sYXp5OwogICAgcy5nb29kX21hdGNoID0gY29uZmlndXJhdGlvbl90YWJsZVtzLmxldmVsXS5nb29kX2xlbmd0aDsKICAgIHMubmljZV9tYXRjaCA9IGNvbmZpZ3VyYXRpb25fdGFibGVbcy5sZXZlbF0ubmljZV9sZW5ndGg7CiAgICBzLm1heF9jaGFpbl9sZW5ndGggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9jaGFpbjsKICAgIHMuc3Ryc3RhcnQgPSAwOwogICAgcy5ibG9ja19zdGFydCA9IDA7CiAgICBzLmxvb2thaGVhZCA9IDA7CiAgICBzLmluc2VydCA9IDA7CiAgICBzLm1hdGNoX2xlbmd0aCA9IHMucHJldl9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxOwogICAgcy5tYXRjaF9hdmFpbGFibGUgPSAwOwogICAgcy5pbnNfaCA9IDA7CiAgfTsKICBmdW5jdGlvbiBEZWZsYXRlU3RhdGUoKSB7CiAgICB0aGlzLnN0cm0gPSBudWxsOyAvKiBwb2ludGVyIGJhY2sgdG8gdGhpcyB6bGliIHN0cmVhbSAqLwogICAgdGhpcy5zdGF0dXMgPSAwOyAvKiBhcyB0aGUgbmFtZSBpbXBsaWVzICovCiAgICB0aGlzLnBlbmRpbmdfYnVmID0gbnVsbDsgLyogb3V0cHV0IHN0aWxsIHBlbmRpbmcgKi8KICAgIHRoaXMucGVuZGluZ19idWZfc2l6ZSA9IDA7IC8qIHNpemUgb2YgcGVuZGluZ19idWYgKi8KICAgIHRoaXMucGVuZGluZ19vdXQgPSAwOyAvKiBuZXh0IHBlbmRpbmcgYnl0ZSB0byBvdXRwdXQgdG8gdGhlIHN0cmVhbSAqLwogICAgdGhpcy5wZW5kaW5nID0gMDsgLyogbmIgb2YgYnl0ZXMgaW4gdGhlIHBlbmRpbmcgYnVmZmVyICovCiAgICB0aGlzLndyYXAgPSAwOyAvKiBiaXQgMCB0cnVlIGZvciB6bGliLCBiaXQgMSB0cnVlIGZvciBnemlwICovCiAgICB0aGlzLmd6aGVhZCA9IG51bGw7IC8qIGd6aXAgaGVhZGVyIGluZm9ybWF0aW9uIHRvIHdyaXRlICovCiAgICB0aGlzLmd6aW5kZXggPSAwOyAvKiB3aGVyZSBpbiBleHRyYSwgbmFtZSwgb3IgY29tbWVudCAqLwogICAgdGhpcy5tZXRob2QgPSBaX0RFRkxBVEVEJDI7IC8qIGNhbiBvbmx5IGJlIERFRkxBVEVEICovCiAgICB0aGlzLmxhc3RfZmx1c2ggPSAtMTsgLyogdmFsdWUgb2YgZmx1c2ggcGFyYW0gZm9yIHByZXZpb3VzIGRlZmxhdGUgY2FsbCAqLwoKICAgIHRoaXMud19zaXplID0gMDsgLyogTFo3NyB3aW5kb3cgc2l6ZSAoMzJLIGJ5IGRlZmF1bHQpICovCiAgICB0aGlzLndfYml0cyA9IDA7IC8qIGxvZzIod19zaXplKSAgKDguLjE2KSAqLwogICAgdGhpcy53X21hc2sgPSAwOyAvKiB3X3NpemUgLSAxICovCgogICAgdGhpcy53aW5kb3cgPSBudWxsOwogICAgLyogU2xpZGluZyB3aW5kb3cuIElucHV0IGJ5dGVzIGFyZSByZWFkIGludG8gdGhlIHNlY29uZCBoYWxmIG9mIHRoZSB3aW5kb3csCiAgICAgKiBhbmQgbW92ZSB0byB0aGUgZmlyc3QgaGFsZiBsYXRlciB0byBrZWVwIGEgZGljdGlvbmFyeSBvZiBhdCBsZWFzdCB3U2l6ZQogICAgICogYnl0ZXMuIFdpdGggdGhpcyBvcmdhbml6YXRpb24sIG1hdGNoZXMgYXJlIGxpbWl0ZWQgdG8gYSBkaXN0YW5jZSBvZgogICAgICogd1NpemUtTUFYX01BVENIIGJ5dGVzLCBidXQgdGhpcyBlbnN1cmVzIHRoYXQgSU8gaXMgYWx3YXlzCiAgICAgKiBwZXJmb3JtZWQgd2l0aCBhIGxlbmd0aCBtdWx0aXBsZSBvZiB0aGUgYmxvY2sgc2l6ZS4KICAgICAqLwoKICAgIHRoaXMud2luZG93X3NpemUgPSAwOwogICAgLyogQWN0dWFsIHNpemUgb2Ygd2luZG93OiAyKndTaXplLCBleGNlcHQgd2hlbiB0aGUgdXNlciBpbnB1dCBidWZmZXIKICAgICAqIGlzIGRpcmVjdGx5IHVzZWQgYXMgc2xpZGluZyB3aW5kb3cuCiAgICAgKi8KCiAgICB0aGlzLnByZXYgPSBudWxsOwogICAgLyogTGluayB0byBvbGRlciBzdHJpbmcgd2l0aCBzYW1lIGhhc2ggaW5kZXguIFRvIGxpbWl0IHRoZSBzaXplIG9mIHRoaXMKICAgICAqIGFycmF5IHRvIDY0SywgdGhpcyBsaW5rIGlzIG1haW50YWluZWQgb25seSBmb3IgdGhlIGxhc3QgMzJLIHN0cmluZ3MuCiAgICAgKiBBbiBpbmRleCBpbiB0aGlzIGFycmF5IGlzIHRodXMgYSB3aW5kb3cgaW5kZXggbW9kdWxvIDMySy4KICAgICAqLwoKICAgIHRoaXMuaGVhZCA9IG51bGw7IC8qIEhlYWRzIG9mIHRoZSBoYXNoIGNoYWlucyBvciBOSUwuICovCgogICAgdGhpcy5pbnNfaCA9IDA7IC8qIGhhc2ggaW5kZXggb2Ygc3RyaW5nIHRvIGJlIGluc2VydGVkICovCiAgICB0aGlzLmhhc2hfc2l6ZSA9IDA7IC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiBoYXNoIHRhYmxlICovCiAgICB0aGlzLmhhc2hfYml0cyA9IDA7IC8qIGxvZzIoaGFzaF9zaXplKSAqLwogICAgdGhpcy5oYXNoX21hc2sgPSAwOyAvKiBoYXNoX3NpemUtMSAqLwoKICAgIHRoaXMuaGFzaF9zaGlmdCA9IDA7CiAgICAvKiBOdW1iZXIgb2YgYml0cyBieSB3aGljaCBpbnNfaCBtdXN0IGJlIHNoaWZ0ZWQgYXQgZWFjaCBpbnB1dAogICAgICogc3RlcC4gSXQgbXVzdCBiZSBzdWNoIHRoYXQgYWZ0ZXIgTUlOX01BVENIIHN0ZXBzLCB0aGUgb2xkZXN0CiAgICAgKiBieXRlIG5vIGxvbmdlciB0YWtlcyBwYXJ0IGluIHRoZSBoYXNoIGtleSwgdGhhdCBpczoKICAgICAqICAgaGFzaF9zaGlmdCAqIE1JTl9NQVRDSCA+PSBoYXNoX2JpdHMKICAgICAqLwoKICAgIHRoaXMuYmxvY2tfc3RhcnQgPSAwOwogICAgLyogV2luZG93IHBvc2l0aW9uIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGN1cnJlbnQgb3V0cHV0IGJsb2NrLiBHZXRzCiAgICAgKiBuZWdhdGl2ZSB3aGVuIHRoZSB3aW5kb3cgaXMgbW92ZWQgYmFja3dhcmRzLgogICAgICovCgogICAgdGhpcy5tYXRjaF9sZW5ndGggPSAwOyAvKiBsZW5ndGggb2YgYmVzdCBtYXRjaCAqLwogICAgdGhpcy5wcmV2X21hdGNoID0gMDsgLyogcHJldmlvdXMgbWF0Y2ggKi8KICAgIHRoaXMubWF0Y2hfYXZhaWxhYmxlID0gMDsgLyogc2V0IGlmIHByZXZpb3VzIG1hdGNoIGV4aXN0cyAqLwogICAgdGhpcy5zdHJzdGFydCA9IDA7IC8qIHN0YXJ0IG9mIHN0cmluZyB0byBpbnNlcnQgKi8KICAgIHRoaXMubWF0Y2hfc3RhcnQgPSAwOyAvKiBzdGFydCBvZiBtYXRjaGluZyBzdHJpbmcgKi8KICAgIHRoaXMubG9va2FoZWFkID0gMDsgLyogbnVtYmVyIG9mIHZhbGlkIGJ5dGVzIGFoZWFkIGluIHdpbmRvdyAqLwoKICAgIHRoaXMucHJldl9sZW5ndGggPSAwOwogICAgLyogTGVuZ3RoIG9mIHRoZSBiZXN0IG1hdGNoIGF0IHByZXZpb3VzIHN0ZXAuIE1hdGNoZXMgbm90IGdyZWF0ZXIgdGhhbiB0aGlzCiAgICAgKiBhcmUgZGlzY2FyZGVkLiBUaGlzIGlzIHVzZWQgaW4gdGhlIGxhenkgbWF0Y2ggZXZhbHVhdGlvbi4KICAgICAqLwoKICAgIHRoaXMubWF4X2NoYWluX2xlbmd0aCA9IDA7CiAgICAvKiBUbyBzcGVlZCB1cCBkZWZsYXRpb24sIGhhc2ggY2hhaW5zIGFyZSBuZXZlciBzZWFyY2hlZCBiZXlvbmQgdGhpcwogICAgICogbGVuZ3RoLiAgQSBoaWdoZXIgbGltaXQgaW1wcm92ZXMgY29tcHJlc3Npb24gcmF0aW8gYnV0IGRlZ3JhZGVzIHRoZQogICAgICogc3BlZWQuCiAgICAgKi8KCiAgICB0aGlzLm1heF9sYXp5X21hdGNoID0gMDsKICAgIC8qIEF0dGVtcHQgdG8gZmluZCBhIGJldHRlciBtYXRjaCBvbmx5IHdoZW4gdGhlIGN1cnJlbnQgbWF0Y2ggaXMgc3RyaWN0bHkKICAgICAqIHNtYWxsZXIgdGhhbiB0aGlzIHZhbHVlLiBUaGlzIG1lY2hhbmlzbSBpcyB1c2VkIG9ubHkgZm9yIGNvbXByZXNzaW9uCiAgICAgKiBsZXZlbHMgPj0gNC4KICAgICAqLwogICAgLy8gVGhhdCdzIGFsaWFzIHRvIG1heF9sYXp5X21hdGNoLCBkb24ndCB1c2UgZGlyZWN0bHkKICAgIC8vdGhpcy5tYXhfaW5zZXJ0X2xlbmd0aCA9IDA7CiAgICAvKiBJbnNlcnQgbmV3IHN0cmluZ3MgaW4gdGhlIGhhc2ggdGFibGUgb25seSBpZiB0aGUgbWF0Y2ggbGVuZ3RoIGlzIG5vdAogICAgICogZ3JlYXRlciB0aGFuIHRoaXMgbGVuZ3RoLiBUaGlzIHNhdmVzIHRpbWUgYnV0IGRlZ3JhZGVzIGNvbXByZXNzaW9uLgogICAgICogbWF4X2luc2VydF9sZW5ndGggaXMgdXNlZCBvbmx5IGZvciBjb21wcmVzc2lvbiBsZXZlbHMgPD0gMy4KICAgICAqLwoKICAgIHRoaXMubGV2ZWwgPSAwOyAvKiBjb21wcmVzc2lvbiBsZXZlbCAoMS4uOSkgKi8KICAgIHRoaXMuc3RyYXRlZ3kgPSAwOyAvKiBmYXZvciBvciBmb3JjZSBIdWZmbWFuIGNvZGluZyovCgogICAgdGhpcy5nb29kX21hdGNoID0gMDsKICAgIC8qIFVzZSBhIGZhc3RlciBzZWFyY2ggd2hlbiB0aGUgcHJldmlvdXMgbWF0Y2ggaXMgbG9uZ2VyIHRoYW4gdGhpcyAqLwoKICAgIHRoaXMubmljZV9tYXRjaCA9IDA7IC8qIFN0b3Agc2VhcmNoaW5nIHdoZW4gY3VycmVudCBtYXRjaCBleGNlZWRzIHRoaXMgKi8KCiAgICAvKiB1c2VkIGJ5IHRyZWVzLmM6ICovCgogICAgLyogRGlkbid0IHVzZSBjdF9kYXRhIHR5cGVkZWYgYmVsb3cgdG8gc3VwcHJlc3MgY29tcGlsZXIgd2FybmluZyAqLwoKICAgIC8vIHN0cnVjdCBjdF9kYXRhX3MgZHluX2x0cmVlW0hFQVBfU0laRV07ICAgLyogbGl0ZXJhbCBhbmQgbGVuZ3RoIHRyZWUgKi8KICAgIC8vIHN0cnVjdCBjdF9kYXRhX3MgZHluX2R0cmVlWzIqRF9DT0RFUysxXTsgLyogZGlzdGFuY2UgdHJlZSAqLwogICAgLy8gc3RydWN0IGN0X2RhdGFfcyBibF90cmVlWzIqQkxfQ09ERVMrMV07ICAvKiBIdWZmbWFuIHRyZWUgZm9yIGJpdCBsZW5ndGhzICovCgogICAgLy8gVXNlIGZsYXQgYXJyYXkgb2YgRE9VQkxFIHNpemUsIHdpdGggaW50ZXJsZWF2ZWQgZmF0YSwKICAgIC8vIGJlY2F1c2UgSlMgZG9lcyBub3Qgc3VwcG9ydCBlZmZlY3RpdmUKICAgIHRoaXMuZHluX2x0cmVlID0gbmV3IFVpbnQxNkFycmF5KEhFQVBfU0laRSAqIDIpOwogICAgdGhpcy5keW5fZHRyZWUgPSBuZXcgVWludDE2QXJyYXkoKDIgKiBEX0NPREVTICsgMSkgKiAyKTsKICAgIHRoaXMuYmxfdHJlZSA9IG5ldyBVaW50MTZBcnJheSgoMiAqIEJMX0NPREVTICsgMSkgKiAyKTsKICAgIHplcm8odGhpcy5keW5fbHRyZWUpOwogICAgemVybyh0aGlzLmR5bl9kdHJlZSk7CiAgICB6ZXJvKHRoaXMuYmxfdHJlZSk7CiAgICB0aGlzLmxfZGVzYyA9IG51bGw7IC8qIGRlc2MuIGZvciBsaXRlcmFsIHRyZWUgKi8KICAgIHRoaXMuZF9kZXNjID0gbnVsbDsgLyogZGVzYy4gZm9yIGRpc3RhbmNlIHRyZWUgKi8KICAgIHRoaXMuYmxfZGVzYyA9IG51bGw7IC8qIGRlc2MuIGZvciBiaXQgbGVuZ3RoIHRyZWUgKi8KCiAgICAvL3VzaCBibF9jb3VudFtNQVhfQklUUysxXTsKICAgIHRoaXMuYmxfY291bnQgPSBuZXcgVWludDE2QXJyYXkoTUFYX0JJVFMgKyAxKTsKICAgIC8qIG51bWJlciBvZiBjb2RlcyBhdCBlYWNoIGJpdCBsZW5ndGggZm9yIGFuIG9wdGltYWwgdHJlZSAqLwoKICAgIC8vaW50IGhlYXBbMipMX0NPREVTKzFdOyAgICAgIC8qIGhlYXAgdXNlZCB0byBidWlsZCB0aGUgSHVmZm1hbiB0cmVlcyAqLwogICAgdGhpcy5oZWFwID0gbmV3IFVpbnQxNkFycmF5KDIgKiBMX0NPREVTICsgMSk7IC8qIGhlYXAgdXNlZCB0byBidWlsZCB0aGUgSHVmZm1hbiB0cmVlcyAqLwogICAgemVybyh0aGlzLmhlYXApOwogICAgdGhpcy5oZWFwX2xlbiA9IDA7IC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgaGVhcCAqLwogICAgdGhpcy5oZWFwX21heCA9IDA7IC8qIGVsZW1lbnQgb2YgbGFyZ2VzdCBmcmVxdWVuY3kgKi8KICAgIC8qIFRoZSBzb25zIG9mIGhlYXBbbl0gYXJlIGhlYXBbMipuXSBhbmQgaGVhcFsyKm4rMV0uIGhlYXBbMF0gaXMgbm90IHVzZWQuCiAgICAgKiBUaGUgc2FtZSBoZWFwIGFycmF5IGlzIHVzZWQgdG8gYnVpbGQgYWxsIHRyZWVzLgogICAgICovCgogICAgdGhpcy5kZXB0aCA9IG5ldyBVaW50MTZBcnJheSgyICogTF9DT0RFUyArIDEpOyAvL3VjaCBkZXB0aFsyKkxfQ09ERVMrMV07CiAgICB6ZXJvKHRoaXMuZGVwdGgpOwogICAgLyogRGVwdGggb2YgZWFjaCBzdWJ0cmVlIHVzZWQgYXMgdGllIGJyZWFrZXIgZm9yIHRyZWVzIG9mIGVxdWFsIGZyZXF1ZW5jeQogICAgICovCgogICAgdGhpcy5sX2J1ZiA9IDA7IC8qIGJ1ZmZlciBpbmRleCBmb3IgbGl0ZXJhbHMgb3IgbGVuZ3RocyAqLwoKICAgIHRoaXMubGl0X2J1ZnNpemUgPSAwOwogICAgLyogU2l6ZSBvZiBtYXRjaCBidWZmZXIgZm9yIGxpdGVyYWxzL2xlbmd0aHMuICBUaGVyZSBhcmUgNCByZWFzb25zIGZvcgogICAgICogbGltaXRpbmcgbGl0X2J1ZnNpemUgdG8gNjRLOgogICAgICogICAtIGZyZXF1ZW5jaWVzIGNhbiBiZSBrZXB0IGluIDE2IGJpdCBjb3VudGVycwogICAgICogICAtIGlmIGNvbXByZXNzaW9uIGlzIG5vdCBzdWNjZXNzZnVsIGZvciB0aGUgZmlyc3QgYmxvY2ssIGFsbCBpbnB1dAogICAgICogICAgIGRhdGEgaXMgc3RpbGwgaW4gdGhlIHdpbmRvdyBzbyB3ZSBjYW4gc3RpbGwgZW1pdCBhIHN0b3JlZCBibG9jayBldmVuCiAgICAgKiAgICAgd2hlbiBpbnB1dCBjb21lcyBmcm9tIHN0YW5kYXJkIGlucHV0LiAgKFRoaXMgY2FuIGFsc28gYmUgZG9uZSBmb3IKICAgICAqICAgICBhbGwgYmxvY2tzIGlmIGxpdF9idWZzaXplIGlzIG5vdCBncmVhdGVyIHRoYW4gMzJLLikKICAgICAqICAgLSBpZiBjb21wcmVzc2lvbiBpcyBub3Qgc3VjY2Vzc2Z1bCBmb3IgYSBmaWxlIHNtYWxsZXIgdGhhbiA2NEssIHdlIGNhbgogICAgICogICAgIGV2ZW4gZW1pdCBhIHN0b3JlZCBmaWxlIGluc3RlYWQgb2YgYSBzdG9yZWQgYmxvY2sgKHNhdmluZyA1IGJ5dGVzKS4KICAgICAqICAgICBUaGlzIGlzIGFwcGxpY2FibGUgb25seSBmb3IgemlwIChub3QgZ3ppcCBvciB6bGliKS4KICAgICAqICAgLSBjcmVhdGluZyBuZXcgSHVmZm1hbiB0cmVlcyBsZXNzIGZyZXF1ZW50bHkgbWF5IG5vdCBwcm92aWRlIGZhc3QKICAgICAqICAgICBhZGFwdGF0aW9uIHRvIGNoYW5nZXMgaW4gdGhlIGlucHV0IGRhdGEgc3RhdGlzdGljcy4gKFRha2UgZm9yCiAgICAgKiAgICAgZXhhbXBsZSBhIGJpbmFyeSBmaWxlIHdpdGggcG9vcmx5IGNvbXByZXNzaWJsZSBjb2RlIGZvbGxvd2VkIGJ5CiAgICAgKiAgICAgYSBoaWdobHkgY29tcHJlc3NpYmxlIHN0cmluZyB0YWJsZS4pIFNtYWxsZXIgYnVmZmVyIHNpemVzIGdpdmUKICAgICAqICAgICBmYXN0IGFkYXB0YXRpb24gYnV0IGhhdmUgb2YgY291cnNlIHRoZSBvdmVyaGVhZCBvZiB0cmFuc21pdHRpbmcKICAgICAqICAgICB0cmVlcyBtb3JlIGZyZXF1ZW50bHkuCiAgICAgKiAgIC0gSSBjYW4ndCBjb3VudCBhYm92ZSA0CiAgICAgKi8KCiAgICB0aGlzLmxhc3RfbGl0ID0gMDsgLyogcnVubmluZyBpbmRleCBpbiBsX2J1ZiAqLwoKICAgIHRoaXMuZF9idWYgPSAwOwogICAgLyogQnVmZmVyIGluZGV4IGZvciBkaXN0YW5jZXMuIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLCBkX2J1ZiBhbmQgbF9idWYgaGF2ZQogICAgICogdGhlIHNhbWUgbnVtYmVyIG9mIGVsZW1lbnRzLiBUbyB1c2UgZGlmZmVyZW50IGxlbmd0aHMsIGFuIGV4dHJhIGZsYWcKICAgICAqIGFycmF5IHdvdWxkIGJlIG5lY2Vzc2FyeS4KICAgICAqLwoKICAgIHRoaXMub3B0X2xlbiA9IDA7IC8qIGJpdCBsZW5ndGggb2YgY3VycmVudCBibG9jayB3aXRoIG9wdGltYWwgdHJlZXMgKi8KICAgIHRoaXMuc3RhdGljX2xlbiA9IDA7IC8qIGJpdCBsZW5ndGggb2YgY3VycmVudCBibG9jayB3aXRoIHN0YXRpYyB0cmVlcyAqLwogICAgdGhpcy5tYXRjaGVzID0gMDsgLyogbnVtYmVyIG9mIHN0cmluZyBtYXRjaGVzIGluIGN1cnJlbnQgYmxvY2sgKi8KICAgIHRoaXMuaW5zZXJ0ID0gMDsgLyogYnl0ZXMgYXQgZW5kIG9mIHdpbmRvdyBsZWZ0IHRvIGluc2VydCAqLwoKICAgIHRoaXMuYmlfYnVmID0gMDsKICAgIC8qIE91dHB1dCBidWZmZXIuIGJpdHMgYXJlIGluc2VydGVkIHN0YXJ0aW5nIGF0IHRoZSBib3R0b20gKGxlYXN0CiAgICAgKiBzaWduaWZpY2FudCBiaXRzKS4KICAgICAqLwogICAgdGhpcy5iaV92YWxpZCA9IDA7CiAgICAvKiBOdW1iZXIgb2YgdmFsaWQgYml0cyBpbiBiaV9idWYuICBBbGwgYml0cyBhYm92ZSB0aGUgbGFzdCB2YWxpZCBiaXQKICAgICAqIGFyZSBhbHdheXMgemVyby4KICAgICAqLwoKICAgIC8vIFVzZWQgZm9yIHdpbmRvdyBtZW1vcnkgaW5pdC4gV2Ugc2FmZWx5IGlnbm9yZSBpdCBmb3IgSlMuIFRoYXQgbWFrZXMKICAgIC8vIHNlbnNlIG9ubHkgZm9yIHBvaW50ZXJzIGFuZCBtZW1vcnkgY2hlY2sgdG9vbHMuCiAgICAvL3RoaXMuaGlnaF93YXRlciA9IDA7CiAgICAvKiBIaWdoIHdhdGVyIG1hcmsgb2Zmc2V0IGluIHdpbmRvdyBmb3IgaW5pdGlhbGl6ZWQgYnl0ZXMgLS0gYnl0ZXMgYWJvdmUKICAgICAqIHRoaXMgYXJlIHNldCB0byB6ZXJvIGluIG9yZGVyIHRvIGF2b2lkIG1lbW9yeSBjaGVjayB3YXJuaW5ncyB3aGVuCiAgICAgKiBsb25nZXN0IG1hdGNoIHJvdXRpbmVzIGFjY2VzcyBieXRlcyBwYXN0IHRoZSBpbnB1dC4gIFRoaXMgaXMgdGhlbgogICAgICogdXBkYXRlZCB0byB0aGUgbmV3IGhpZ2ggd2F0ZXIgbWFyay4KICAgICAqLwogIH0KICB2YXIgZGVmbGF0ZVJlc2V0S2VlcCA9IGZ1bmN0aW9uIGRlZmxhdGVSZXNldEtlZXAoc3RybSkgewogICAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7CiAgICAgIHJldHVybiBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IkMik7CiAgICB9CiAgICBzdHJtLnRvdGFsX2luID0gc3RybS50b3RhbF9vdXQgPSAwOwogICAgc3RybS5kYXRhX3R5cGUgPSBaX1VOS05PV047CiAgICB2YXIgcyA9IHN0cm0uc3RhdGU7CiAgICBzLnBlbmRpbmcgPSAwOwogICAgcy5wZW5kaW5nX291dCA9IDA7CiAgICBpZiAocy53cmFwIDwgMCkgewogICAgICBzLndyYXAgPSAtcy53cmFwOwogICAgICAvKiB3YXMgbWFkZSBuZWdhdGl2ZSBieSBkZWZsYXRlKC4uLiwgWl9GSU5JU0gpOyAqLwogICAgfQogICAgcy5zdGF0dXMgPSBzLndyYXAgPyBJTklUX1NUQVRFIDogQlVTWV9TVEFURTsKICAgIHN0cm0uYWRsZXIgPSBzLndyYXAgPT09IDIgPyAwIC8vIGNyYzMyKDAsIFpfTlVMTCwgMCkKICAgIDogMTsgLy8gYWRsZXIzMigwLCBaX05VTEwsIDApCiAgICBzLmxhc3RfZmx1c2ggPSBaX05PX0ZMVVNIJDI7CiAgICBfdHJfaW5pdChzKTsKICAgIHJldHVybiBaX09LJDM7CiAgfTsKICB2YXIgZGVmbGF0ZVJlc2V0ID0gZnVuY3Rpb24gZGVmbGF0ZVJlc2V0KHN0cm0pIHsKICAgIHZhciByZXQgPSBkZWZsYXRlUmVzZXRLZWVwKHN0cm0pOwogICAgaWYgKHJldCA9PT0gWl9PSyQzKSB7CiAgICAgIGxtX2luaXQoc3RybS5zdGF0ZSk7CiAgICB9CiAgICByZXR1cm4gcmV0OwogIH07CiAgdmFyIGRlZmxhdGVTZXRIZWFkZXIgPSBmdW5jdGlvbiBkZWZsYXRlU2V0SGVhZGVyKHN0cm0sIGhlYWQpIHsKICAgIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMjsKICAgIH0KICAgIGlmIChzdHJtLnN0YXRlLndyYXAgIT09IDIpIHsKICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDI7CiAgICB9CiAgICBzdHJtLnN0YXRlLmd6aGVhZCA9IGhlYWQ7CiAgICByZXR1cm4gWl9PSyQzOwogIH07CiAgdmFyIGRlZmxhdGVJbml0MiA9IGZ1bmN0aW9uIGRlZmxhdGVJbml0MihzdHJtLCBsZXZlbCwgbWV0aG9kLCB3aW5kb3dCaXRzLCBtZW1MZXZlbCwgc3RyYXRlZ3kpIHsKICAgIGlmICghc3RybSkgewogICAgICAvLyA9PT0gWl9OVUxMCiAgICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUiQyOwogICAgfQogICAgdmFyIHdyYXAgPSAxOwogICAgaWYgKGxldmVsID09PSBaX0RFRkFVTFRfQ09NUFJFU1NJT04kMSkgewogICAgICBsZXZlbCA9IDY7CiAgICB9CiAgICBpZiAod2luZG93Qml0cyA8IDApIHsKICAgICAgLyogc3VwcHJlc3MgemxpYiB3cmFwcGVyICovCiAgICAgIHdyYXAgPSAwOwogICAgICB3aW5kb3dCaXRzID0gLXdpbmRvd0JpdHM7CiAgICB9IGVsc2UgaWYgKHdpbmRvd0JpdHMgPiAxNSkgewogICAgICB3cmFwID0gMjsgLyogd3JpdGUgZ3ppcCB3cmFwcGVyIGluc3RlYWQgKi8KICAgICAgd2luZG93Qml0cyAtPSAxNjsKICAgIH0KICAgIGlmIChtZW1MZXZlbCA8IDEgfHwgbWVtTGV2ZWwgPiBNQVhfTUVNX0xFVkVMIHx8IG1ldGhvZCAhPT0gWl9ERUZMQVRFRCQyIHx8IHdpbmRvd0JpdHMgPCA4IHx8IHdpbmRvd0JpdHMgPiAxNSB8fCBsZXZlbCA8IDAgfHwgbGV2ZWwgPiA5IHx8IHN0cmF0ZWd5IDwgMCB8fCBzdHJhdGVneSA+IFpfRklYRUQpIHsKICAgICAgcmV0dXJuIGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUiQyKTsKICAgIH0KICAgIGlmICh3aW5kb3dCaXRzID09PSA4KSB7CiAgICAgIHdpbmRvd0JpdHMgPSA5OwogICAgfQogICAgLyogdW50aWwgMjU2LWJ5dGUgd2luZG93IGJ1ZyBmaXhlZCAqLwoKICAgIHZhciBzID0gbmV3IERlZmxhdGVTdGF0ZSgpOwogICAgc3RybS5zdGF0ZSA9IHM7CiAgICBzLnN0cm0gPSBzdHJtOwogICAgcy53cmFwID0gd3JhcDsKICAgIHMuZ3poZWFkID0gbnVsbDsKICAgIHMud19iaXRzID0gd2luZG93Qml0czsKICAgIHMud19zaXplID0gMSA8PCBzLndfYml0czsKICAgIHMud19tYXNrID0gcy53X3NpemUgLSAxOwogICAgcy5oYXNoX2JpdHMgPSBtZW1MZXZlbCArIDc7CiAgICBzLmhhc2hfc2l6ZSA9IDEgPDwgcy5oYXNoX2JpdHM7CiAgICBzLmhhc2hfbWFzayA9IHMuaGFzaF9zaXplIC0gMTsKICAgIHMuaGFzaF9zaGlmdCA9IH5+KChzLmhhc2hfYml0cyArIE1JTl9NQVRDSCAtIDEpIC8gTUlOX01BVENIKTsKICAgIHMud2luZG93ID0gbmV3IFVpbnQ4QXJyYXkocy53X3NpemUgKiAyKTsKICAgIHMuaGVhZCA9IG5ldyBVaW50MTZBcnJheShzLmhhc2hfc2l6ZSk7CiAgICBzLnByZXYgPSBuZXcgVWludDE2QXJyYXkocy53X3NpemUpOwoKICAgIC8vIERvbid0IG5lZWQgbWVtIGluaXQgbWFnaWMgZm9yIEpTLgogICAgLy9zLmhpZ2hfd2F0ZXIgPSAwOyAgLyogbm90aGluZyB3cml0dGVuIHRvIHMtPndpbmRvdyB5ZXQgKi8KCiAgICBzLmxpdF9idWZzaXplID0gMSA8PCBtZW1MZXZlbCArIDY7IC8qIDE2SyBlbGVtZW50cyBieSBkZWZhdWx0ICovCgogICAgcy5wZW5kaW5nX2J1Zl9zaXplID0gcy5saXRfYnVmc2l6ZSAqIDQ7CgogICAgLy9vdmVybGF5ID0gKHVzaGYgKikgWkFMTE9DKHN0cm0sIHMtPmxpdF9idWZzaXplLCBzaXplb2YodXNoKSsyKTsKICAgIC8vcy0+cGVuZGluZ19idWYgPSAodWNoZiAqKSBvdmVybGF5OwogICAgcy5wZW5kaW5nX2J1ZiA9IG5ldyBVaW50OEFycmF5KHMucGVuZGluZ19idWZfc2l6ZSk7CgogICAgLy8gSXQgaXMgb2Zmc2V0IGZyb20gYHMucGVuZGluZ19idWZgIChzaXplIGlzIGBzLmxpdF9idWZzaXplICogMmApCiAgICAvL3MtPmRfYnVmID0gb3ZlcmxheSArIHMtPmxpdF9idWZzaXplL3NpemVvZih1c2gpOwogICAgcy5kX2J1ZiA9IDEgKiBzLmxpdF9idWZzaXplOwoKICAgIC8vcy0+bF9idWYgPSBzLT5wZW5kaW5nX2J1ZiArICgxK3NpemVvZih1c2gpKSpzLT5saXRfYnVmc2l6ZTsKICAgIHMubF9idWYgPSAoMSArIDIpICogcy5saXRfYnVmc2l6ZTsKICAgIHMubGV2ZWwgPSBsZXZlbDsKICAgIHMuc3RyYXRlZ3kgPSBzdHJhdGVneTsKICAgIHMubWV0aG9kID0gbWV0aG9kOwogICAgcmV0dXJuIGRlZmxhdGVSZXNldChzdHJtKTsKICB9OwogIHZhciBkZWZsYXRlSW5pdCA9IGZ1bmN0aW9uIGRlZmxhdGVJbml0KHN0cm0sIGxldmVsKSB7CiAgICByZXR1cm4gZGVmbGF0ZUluaXQyKHN0cm0sIGxldmVsLCBaX0RFRkxBVEVEJDIsIE1BWF9XQklUUyQxLCBERUZfTUVNX0xFVkVMLCBaX0RFRkFVTFRfU1RSQVRFR1kkMSk7CiAgfTsKICB2YXIgZGVmbGF0ZSQyID0gZnVuY3Rpb24gZGVmbGF0ZShzdHJtLCBmbHVzaCkgewogICAgdmFyIGJlZywgdmFsOyAvLyBmb3IgZ3ppcCBoZWFkZXIgd3JpdGUgb25seQoKICAgIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSB8fCBmbHVzaCA+IFpfQkxPQ0skMSB8fCBmbHVzaCA8IDApIHsKICAgICAgcmV0dXJuIHN0cm0gPyBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IkMikgOiBaX1NUUkVBTV9FUlJPUiQyOwogICAgfQogICAgdmFyIHMgPSBzdHJtLnN0YXRlOwogICAgaWYgKCFzdHJtLm91dHB1dCB8fCAhc3RybS5pbnB1dCAmJiBzdHJtLmF2YWlsX2luICE9PSAwIHx8IHMuc3RhdHVzID09PSBGSU5JU0hfU1RBVEUgJiYgZmx1c2ggIT09IFpfRklOSVNIJDMpIHsKICAgICAgcmV0dXJuIGVycihzdHJtLCBzdHJtLmF2YWlsX291dCA9PT0gMCA/IFpfQlVGX0VSUk9SJDEgOiBaX1NUUkVBTV9FUlJPUiQyKTsKICAgIH0KICAgIHMuc3RybSA9IHN0cm07IC8qIGp1c3QgaW4gY2FzZSAqLwogICAgdmFyIG9sZF9mbHVzaCA9IHMubGFzdF9mbHVzaDsKICAgIHMubGFzdF9mbHVzaCA9IGZsdXNoOwoKICAgIC8qIFdyaXRlIHRoZSBoZWFkZXIgKi8KICAgIGlmIChzLnN0YXR1cyA9PT0gSU5JVF9TVEFURSkgewogICAgICBpZiAocy53cmFwID09PSAyKSB7CiAgICAgICAgLy8gR1pJUCBoZWFkZXIKICAgICAgICBzdHJtLmFkbGVyID0gMDsgLy9jcmMzMigwTCwgWl9OVUxMLCAwKTsKICAgICAgICBwdXRfYnl0ZShzLCAzMSk7CiAgICAgICAgcHV0X2J5dGUocywgMTM5KTsKICAgICAgICBwdXRfYnl0ZShzLCA4KTsKICAgICAgICBpZiAoIXMuZ3poZWFkKSB7CiAgICAgICAgICAvLyBzLT5nemhlYWQgPT0gWl9OVUxMCiAgICAgICAgICBwdXRfYnl0ZShzLCAwKTsKICAgICAgICAgIHB1dF9ieXRlKHMsIDApOwogICAgICAgICAgcHV0X2J5dGUocywgMCk7CiAgICAgICAgICBwdXRfYnl0ZShzLCAwKTsKICAgICAgICAgIHB1dF9ieXRlKHMsIDApOwogICAgICAgICAgcHV0X2J5dGUocywgcy5sZXZlbCA9PT0gOSA/IDIgOiBzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyID8gNCA6IDApOwogICAgICAgICAgcHV0X2J5dGUocywgT1NfQ09ERSk7CiAgICAgICAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC50ZXh0ID8gMSA6IDApICsgKHMuZ3poZWFkLmhjcmMgPyAyIDogMCkgKyAoIXMuZ3poZWFkLmV4dHJhID8gMCA6IDQpICsgKCFzLmd6aGVhZC5uYW1lID8gMCA6IDgpICsgKCFzLmd6aGVhZC5jb21tZW50ID8gMCA6IDE2KSk7CiAgICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC50aW1lICYgMHhmZik7CiAgICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC50aW1lID4+IDggJiAweGZmKTsKICAgICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLnRpbWUgPj4gMTYgJiAweGZmKTsKICAgICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLnRpbWUgPj4gMjQgJiAweGZmKTsKICAgICAgICAgIHB1dF9ieXRlKHMsIHMubGV2ZWwgPT09IDkgPyAyIDogcy5zdHJhdGVneSA+PSBaX0hVRkZNQU5fT05MWSB8fCBzLmxldmVsIDwgMiA/IDQgOiAwKTsKICAgICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLm9zICYgMHhmZik7CiAgICAgICAgICBpZiAocy5nemhlYWQuZXh0cmEgJiYgcy5nemhlYWQuZXh0cmEubGVuZ3RoKSB7CiAgICAgICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLmV4dHJhLmxlbmd0aCAmIDB4ZmYpOwogICAgICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC5leHRyYS5sZW5ndGggPj4gOCAmIDB4ZmYpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMpIHsKICAgICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyJDEoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nLCAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHMuZ3ppbmRleCA9IDA7CiAgICAgICAgICBzLnN0YXR1cyA9IEVYVFJBX1NUQVRFOwogICAgICAgIH0KICAgICAgfSBlbHNlCiAgICAgICAgLy8gREVGTEFURSBoZWFkZXIKICAgICAgICB7CiAgICAgICAgICB2YXIgaGVhZGVyID0gWl9ERUZMQVRFRCQyICsgKHMud19iaXRzIC0gOCA8PCA0KSA8PCA4OwogICAgICAgICAgdmFyIGxldmVsX2ZsYWdzID0gLTE7CiAgICAgICAgICBpZiAocy5zdHJhdGVneSA+PSBaX0hVRkZNQU5fT05MWSB8fCBzLmxldmVsIDwgMikgewogICAgICAgICAgICBsZXZlbF9mbGFncyA9IDA7CiAgICAgICAgICB9IGVsc2UgaWYgKHMubGV2ZWwgPCA2KSB7CiAgICAgICAgICAgIGxldmVsX2ZsYWdzID0gMTsKICAgICAgICAgIH0gZWxzZSBpZiAocy5sZXZlbCA9PT0gNikgewogICAgICAgICAgICBsZXZlbF9mbGFncyA9IDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsZXZlbF9mbGFncyA9IDM7CiAgICAgICAgICB9CiAgICAgICAgICBoZWFkZXIgfD0gbGV2ZWxfZmxhZ3MgPDwgNjsKICAgICAgICAgIGlmIChzLnN0cnN0YXJ0ICE9PSAwKSB7CiAgICAgICAgICAgIGhlYWRlciB8PSBQUkVTRVRfRElDVDsKICAgICAgICAgIH0KICAgICAgICAgIGhlYWRlciArPSAzMSAtIGhlYWRlciAlIDMxOwogICAgICAgICAgcy5zdGF0dXMgPSBCVVNZX1NUQVRFOwogICAgICAgICAgcHV0U2hvcnRNU0IocywgaGVhZGVyKTsKCiAgICAgICAgICAvKiBTYXZlIHRoZSBhZGxlcjMyIG9mIHRoZSBwcmVzZXQgZGljdGlvbmFyeTogKi8KICAgICAgICAgIGlmIChzLnN0cnN0YXJ0ICE9PSAwKSB7CiAgICAgICAgICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgPj4+IDE2KTsKICAgICAgICAgICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciAmIDB4ZmZmZik7CiAgICAgICAgICB9CiAgICAgICAgICBzdHJtLmFkbGVyID0gMTsgLy8gYWRsZXIzMigwTCwgWl9OVUxMLCAwKTsKICAgICAgICB9CiAgICB9CgogICAgLy8jaWZkZWYgR1pJUAogICAgaWYgKHMuc3RhdHVzID09PSBFWFRSQV9TVEFURSkgewogICAgICBpZiAocy5nemhlYWQuZXh0cmEgLyogIT0gWl9OVUxMKi8pIHsKICAgICAgICBiZWcgPSBzLnBlbmRpbmc7IC8qIHN0YXJ0IG9mIGJ5dGVzIHRvIHVwZGF0ZSBjcmMgKi8KCiAgICAgICAgd2hpbGUgKHMuZ3ppbmRleCA8IChzLmd6aGVhZC5leHRyYS5sZW5ndGggJiAweGZmZmYpKSB7CiAgICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHsKICAgICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7CiAgICAgICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyJDEoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7CiAgICAgICAgICAgIGJlZyA9IHMucGVuZGluZzsKICAgICAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLmV4dHJhW3MuZ3ppbmRleF0gJiAweGZmKTsKICAgICAgICAgIHMuZ3ppbmRleCsrOwogICAgICAgIH0KICAgICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHsKICAgICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMiQxKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTsKICAgICAgICB9CiAgICAgICAgaWYgKHMuZ3ppbmRleCA9PT0gcy5nemhlYWQuZXh0cmEubGVuZ3RoKSB7CiAgICAgICAgICBzLmd6aW5kZXggPSAwOwogICAgICAgICAgcy5zdGF0dXMgPSBOQU1FX1NUQVRFOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBzLnN0YXR1cyA9IE5BTUVfU1RBVEU7CiAgICAgIH0KICAgIH0KICAgIGlmIChzLnN0YXR1cyA9PT0gTkFNRV9TVEFURSkgewogICAgICBpZiAocy5nemhlYWQubmFtZSAvKiAhPSBaX05VTEwqLykgewogICAgICAgIGJlZyA9IHMucGVuZGluZzsgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqLwogICAgICAgIC8vaW50IHZhbDsKCiAgICAgICAgZG8gewogICAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7CiAgICAgICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykgewogICAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMiQxKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pOwogICAgICAgICAgICBiZWcgPSBzLnBlbmRpbmc7CiAgICAgICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkgewogICAgICAgICAgICAgIHZhbCA9IDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIC8vIEpTIHNwZWNpZmljOiBsaXR0bGUgbWFnaWMgdG8gYWRkIHplcm8gdGVybWluYXRvciB0byBlbmQgb2Ygc3RyaW5nCiAgICAgICAgICBpZiAocy5nemluZGV4IDwgcy5nemhlYWQubmFtZS5sZW5ndGgpIHsKICAgICAgICAgICAgdmFsID0gcy5nemhlYWQubmFtZS5jaGFyQ29kZUF0KHMuZ3ppbmRleCsrKSAmIDB4ZmY7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB2YWwgPSAwOwogICAgICAgICAgfQogICAgICAgICAgcHV0X2J5dGUocywgdmFsKTsKICAgICAgICB9IHdoaWxlICh2YWwgIT09IDApOwogICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykgewogICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyJDEoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpOwogICAgICAgIH0KICAgICAgICBpZiAodmFsID09PSAwKSB7CiAgICAgICAgICBzLmd6aW5kZXggPSAwOwogICAgICAgICAgcy5zdGF0dXMgPSBDT01NRU5UX1NUQVRFOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBzLnN0YXR1cyA9IENPTU1FTlRfU1RBVEU7CiAgICAgIH0KICAgIH0KICAgIGlmIChzLnN0YXR1cyA9PT0gQ09NTUVOVF9TVEFURSkgewogICAgICBpZiAocy5nemhlYWQuY29tbWVudCAvKiAhPSBaX05VTEwqLykgewogICAgICAgIGJlZyA9IHMucGVuZGluZzsgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqLwogICAgICAgIC8vaW50IHZhbDsKCiAgICAgICAgZG8gewogICAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7CiAgICAgICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykgewogICAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMiQxKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pOwogICAgICAgICAgICBiZWcgPSBzLnBlbmRpbmc7CiAgICAgICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkgewogICAgICAgICAgICAgIHZhbCA9IDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIC8vIEpTIHNwZWNpZmljOiBsaXR0bGUgbWFnaWMgdG8gYWRkIHplcm8gdGVybWluYXRvciB0byBlbmQgb2Ygc3RyaW5nCiAgICAgICAgICBpZiAocy5nemluZGV4IDwgcy5nemhlYWQuY29tbWVudC5sZW5ndGgpIHsKICAgICAgICAgICAgdmFsID0gcy5nemhlYWQuY29tbWVudC5jaGFyQ29kZUF0KHMuZ3ppbmRleCsrKSAmIDB4ZmY7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB2YWwgPSAwOwogICAgICAgICAgfQogICAgICAgICAgcHV0X2J5dGUocywgdmFsKTsKICAgICAgICB9IHdoaWxlICh2YWwgIT09IDApOwogICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykgewogICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyJDEoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpOwogICAgICAgIH0KICAgICAgICBpZiAodmFsID09PSAwKSB7CiAgICAgICAgICBzLnN0YXR1cyA9IEhDUkNfU1RBVEU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHMuc3RhdHVzID0gSENSQ19TVEFURTsKICAgICAgfQogICAgfQogICAgaWYgKHMuc3RhdHVzID09PSBIQ1JDX1NUQVRFKSB7CiAgICAgIGlmIChzLmd6aGVhZC5oY3JjKSB7CiAgICAgICAgaWYgKHMucGVuZGluZyArIDIgPiBzLnBlbmRpbmdfYnVmX3NpemUpIHsKICAgICAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7CiAgICAgICAgfQogICAgICAgIGlmIChzLnBlbmRpbmcgKyAyIDw9IHMucGVuZGluZ19idWZfc2l6ZSkgewogICAgICAgICAgcHV0X2J5dGUocywgc3RybS5hZGxlciAmIDB4ZmYpOwogICAgICAgICAgcHV0X2J5dGUocywgc3RybS5hZGxlciA+PiA4ICYgMHhmZik7CiAgICAgICAgICBzdHJtLmFkbGVyID0gMDsgLy9jcmMzMigwTCwgWl9OVUxMLCAwKTsKICAgICAgICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcy5zdGF0dXMgPSBCVVNZX1NUQVRFOwogICAgICB9CiAgICB9CiAgICAvLyNlbmRpZgoKICAgIC8qIEZsdXNoIGFzIG11Y2ggcGVuZGluZyBvdXRwdXQgYXMgcG9zc2libGUgKi8KICAgIGlmIChzLnBlbmRpbmcgIT09IDApIHsKICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTsKICAgICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7CiAgICAgICAgLyogU2luY2UgYXZhaWxfb3V0IGlzIDAsIGRlZmxhdGUgd2lsbCBiZSBjYWxsZWQgYWdhaW4gd2l0aAogICAgICAgICAqIG1vcmUgb3V0cHV0IHNwYWNlLCBidXQgcG9zc2libHkgd2l0aCBib3RoIHBlbmRpbmcgYW5kCiAgICAgICAgICogYXZhaWxfaW4gZXF1YWwgdG8gemVyby4gVGhlcmUgd29uJ3QgYmUgYW55dGhpbmcgdG8gZG8sCiAgICAgICAgICogYnV0IHRoaXMgaXMgbm90IGFuIGVycm9yIHNpdHVhdGlvbiBzbyBtYWtlIHN1cmUgd2UKICAgICAgICAgKiByZXR1cm4gT0sgaW5zdGVhZCBvZiBCVUZfRVJST1IgYXQgbmV4dCBjYWxsIG9mIGRlZmxhdGU6CiAgICAgICAgICovCiAgICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7CiAgICAgICAgcmV0dXJuIFpfT0skMzsKICAgICAgfQoKICAgICAgLyogTWFrZSBzdXJlIHRoZXJlIGlzIHNvbWV0aGluZyB0byBkbyBhbmQgYXZvaWQgZHVwbGljYXRlIGNvbnNlY3V0aXZlCiAgICAgICAqIGZsdXNoZXMuIEZvciByZXBlYXRlZCBhbmQgdXNlbGVzcyBjYWxscyB3aXRoIFpfRklOSVNILCB3ZSBrZWVwCiAgICAgICAqIHJldHVybmluZyBaX1NUUkVBTV9FTkQgaW5zdGVhZCBvZiBaX0JVRl9FUlJPUi4KICAgICAgICovCiAgICB9IGVsc2UgaWYgKHN0cm0uYXZhaWxfaW4gPT09IDAgJiYgcmFuayhmbHVzaCkgPD0gcmFuayhvbGRfZmx1c2gpICYmIGZsdXNoICE9PSBaX0ZJTklTSCQzKSB7CiAgICAgIHJldHVybiBlcnIoc3RybSwgWl9CVUZfRVJST1IkMSk7CiAgICB9CgogICAgLyogVXNlciBtdXN0IG5vdCBwcm92aWRlIG1vcmUgaW5wdXQgYWZ0ZXIgdGhlIGZpcnN0IEZJTklTSDogKi8KICAgIGlmIChzLnN0YXR1cyA9PT0gRklOSVNIX1NUQVRFICYmIHN0cm0uYXZhaWxfaW4gIT09IDApIHsKICAgICAgcmV0dXJuIGVycihzdHJtLCBaX0JVRl9FUlJPUiQxKTsKICAgIH0KCiAgICAvKiBTdGFydCBhIG5ldyBibG9jayBvciBjb250aW51ZSB0aGUgY3VycmVudCBvbmUuCiAgICAgKi8KICAgIGlmIChzdHJtLmF2YWlsX2luICE9PSAwIHx8IHMubG9va2FoZWFkICE9PSAwIHx8IGZsdXNoICE9PSBaX05PX0ZMVVNIJDIgJiYgcy5zdGF0dXMgIT09IEZJTklTSF9TVEFURSkgewogICAgICB2YXIgYnN0YXRlID0gcy5zdHJhdGVneSA9PT0gWl9IVUZGTUFOX09OTFkgPyBkZWZsYXRlX2h1ZmYocywgZmx1c2gpIDogcy5zdHJhdGVneSA9PT0gWl9STEUgPyBkZWZsYXRlX3JsZShzLCBmbHVzaCkgOiBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLmZ1bmMocywgZmx1c2gpOwogICAgICBpZiAoYnN0YXRlID09PSBCU19GSU5JU0hfU1RBUlRFRCB8fCBic3RhdGUgPT09IEJTX0ZJTklTSF9ET05FKSB7CiAgICAgICAgcy5zdGF0dXMgPSBGSU5JU0hfU1RBVEU7CiAgICAgIH0KICAgICAgaWYgKGJzdGF0ZSA9PT0gQlNfTkVFRF9NT1JFIHx8IGJzdGF0ZSA9PT0gQlNfRklOSVNIX1NUQVJURUQpIHsKICAgICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHsKICAgICAgICAgIHMubGFzdF9mbHVzaCA9IC0xOwogICAgICAgICAgLyogYXZvaWQgQlVGX0VSUk9SIG5leHQgY2FsbCwgc2VlIGFib3ZlICovCiAgICAgICAgfQogICAgICAgIHJldHVybiBaX09LJDM7CiAgICAgICAgLyogSWYgZmx1c2ggIT0gWl9OT19GTFVTSCAmJiBhdmFpbF9vdXQgPT0gMCwgdGhlIG5leHQgY2FsbAogICAgICAgICAqIG9mIGRlZmxhdGUgc2hvdWxkIHVzZSB0aGUgc2FtZSBmbHVzaCBwYXJhbWV0ZXIgdG8gbWFrZSBzdXJlCiAgICAgICAgICogdGhhdCB0aGUgZmx1c2ggaXMgY29tcGxldGUuIFNvIHdlIGRvbid0IGhhdmUgdG8gb3V0cHV0IGFuCiAgICAgICAgICogZW1wdHkgYmxvY2sgaGVyZSwgdGhpcyB3aWxsIGJlIGRvbmUgYXQgbmV4dCBjYWxsLiBUaGlzIGFsc28KICAgICAgICAgKiBlbnN1cmVzIHRoYXQgZm9yIGEgdmVyeSBzbWFsbCBvdXRwdXQgYnVmZmVyLCB3ZSBlbWl0IGF0IG1vc3QKICAgICAgICAgKiBvbmUgZW1wdHkgYmxvY2suCiAgICAgICAgICovCiAgICAgIH0KICAgICAgaWYgKGJzdGF0ZSA9PT0gQlNfQkxPQ0tfRE9ORSkgewogICAgICAgIGlmIChmbHVzaCA9PT0gWl9QQVJUSUFMX0ZMVVNIKSB7CiAgICAgICAgICBfdHJfYWxpZ24ocyk7CiAgICAgICAgfSBlbHNlIGlmIChmbHVzaCAhPT0gWl9CTE9DSyQxKSB7CiAgICAgICAgICAvKiBGVUxMX0ZMVVNIIG9yIFNZTkNfRkxVU0ggKi8KCiAgICAgICAgICBfdHJfc3RvcmVkX2Jsb2NrKHMsIDAsIDAsIGZhbHNlKTsKICAgICAgICAgIC8qIEZvciBhIGZ1bGwgZmx1c2gsIHRoaXMgZW1wdHkgYmxvY2sgd2lsbCBiZSByZWNvZ25pemVkCiAgICAgICAgICAgKiBhcyBhIHNwZWNpYWwgbWFya2VyIGJ5IGluZmxhdGVfc3luYygpLgogICAgICAgICAgICovCiAgICAgICAgICBpZiAoZmx1c2ggPT09IFpfRlVMTF9GTFVTSCQxKSB7CiAgICAgICAgICAgIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqLyAvKiBmb3JnZXQgaGlzdG9yeSAqLwogICAgICAgICAgICB6ZXJvKHMuaGVhZCk7IC8vIEZpbGwgd2l0aCBOSUwgKD0gMCk7CgogICAgICAgICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHsKICAgICAgICAgICAgICBzLnN0cnN0YXJ0ID0gMDsKICAgICAgICAgICAgICBzLmJsb2NrX3N0YXJ0ID0gMDsKICAgICAgICAgICAgICBzLmluc2VydCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTsKICAgICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHsKICAgICAgICAgIHMubGFzdF9mbHVzaCA9IC0xOyAvKiBhdm9pZCBCVUZfRVJST1IgYXQgbmV4dCBjYWxsLCBzZWUgYWJvdmUgKi8KICAgICAgICAgIHJldHVybiBaX09LJDM7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAvL0Fzc2VydChzdHJtLT5hdmFpbF9vdXQgPiAwLCAiYnVnMiIpOwogICAgLy9pZiAoc3RybS5hdmFpbF9vdXQgPD0gMCkgeyB0aHJvdyBuZXcgRXJyb3IoImJ1ZzIiKTt9CgogICAgaWYgKGZsdXNoICE9PSBaX0ZJTklTSCQzKSB7CiAgICAgIHJldHVybiBaX09LJDM7CiAgICB9CiAgICBpZiAocy53cmFwIDw9IDApIHsKICAgICAgcmV0dXJuIFpfU1RSRUFNX0VORCQzOwogICAgfQoKICAgIC8qIFdyaXRlIHRoZSB0cmFpbGVyICovCiAgICBpZiAocy53cmFwID09PSAyKSB7CiAgICAgIHB1dF9ieXRlKHMsIHN0cm0uYWRsZXIgJiAweGZmKTsKICAgICAgcHV0X2J5dGUocywgc3RybS5hZGxlciA+PiA4ICYgMHhmZik7CiAgICAgIHB1dF9ieXRlKHMsIHN0cm0uYWRsZXIgPj4gMTYgJiAweGZmKTsKICAgICAgcHV0X2J5dGUocywgc3RybS5hZGxlciA+PiAyNCAmIDB4ZmYpOwogICAgICBwdXRfYnl0ZShzLCBzdHJtLnRvdGFsX2luICYgMHhmZik7CiAgICAgIHB1dF9ieXRlKHMsIHN0cm0udG90YWxfaW4gPj4gOCAmIDB4ZmYpOwogICAgICBwdXRfYnl0ZShzLCBzdHJtLnRvdGFsX2luID4+IDE2ICYgMHhmZik7CiAgICAgIHB1dF9ieXRlKHMsIHN0cm0udG90YWxfaW4gPj4gMjQgJiAweGZmKTsKICAgIH0gZWxzZSB7CiAgICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgPj4+IDE2KTsKICAgICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciAmIDB4ZmZmZik7CiAgICB9CiAgICBmbHVzaF9wZW5kaW5nKHN0cm0pOwogICAgLyogSWYgYXZhaWxfb3V0IGlzIHplcm8sIHRoZSBhcHBsaWNhdGlvbiB3aWxsIGNhbGwgZGVmbGF0ZSBhZ2FpbgogICAgICogdG8gZmx1c2ggdGhlIHJlc3QuCiAgICAgKi8KICAgIGlmIChzLndyYXAgPiAwKSB7CiAgICAgIHMud3JhcCA9IC1zLndyYXA7CiAgICB9CiAgICAvKiB3cml0ZSB0aGUgdHJhaWxlciBvbmx5IG9uY2UhICovCiAgICByZXR1cm4gcy5wZW5kaW5nICE9PSAwID8gWl9PSyQzIDogWl9TVFJFQU1fRU5EJDM7CiAgfTsKICB2YXIgZGVmbGF0ZUVuZCA9IGZ1bmN0aW9uIGRlZmxhdGVFbmQoc3RybSkgewogICAgaWYgKCFzdHJtIC8qPT0gWl9OVUxMKi8gfHwgIXN0cm0uc3RhdGUgLyo9PSBaX05VTEwqLykgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMjsKICAgIH0KICAgIHZhciBzdGF0dXMgPSBzdHJtLnN0YXRlLnN0YXR1czsKICAgIGlmIChzdGF0dXMgIT09IElOSVRfU1RBVEUgJiYgc3RhdHVzICE9PSBFWFRSQV9TVEFURSAmJiBzdGF0dXMgIT09IE5BTUVfU1RBVEUgJiYgc3RhdHVzICE9PSBDT01NRU5UX1NUQVRFICYmIHN0YXR1cyAhPT0gSENSQ19TVEFURSAmJiBzdGF0dXMgIT09IEJVU1lfU1RBVEUgJiYgc3RhdHVzICE9PSBGSU5JU0hfU1RBVEUpIHsKICAgICAgcmV0dXJuIGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUiQyKTsKICAgIH0KICAgIHN0cm0uc3RhdGUgPSBudWxsOwogICAgcmV0dXJuIHN0YXR1cyA9PT0gQlVTWV9TVEFURSA/IGVycihzdHJtLCBaX0RBVEFfRVJST1IkMikgOiBaX09LJDM7CiAgfTsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAqIEluaXRpYWxpemVzIHRoZSBjb21wcmVzc2lvbiBkaWN0aW9uYXJ5IGZyb20gdGhlIGdpdmVuIGJ5dGUKICAgKiBzZXF1ZW5jZSB3aXRob3V0IHByb2R1Y2luZyBhbnkgY29tcHJlc3NlZCBvdXRwdXQuCiAgICovCiAgdmFyIGRlZmxhdGVTZXREaWN0aW9uYXJ5ID0gZnVuY3Rpb24gZGVmbGF0ZVNldERpY3Rpb25hcnkoc3RybSwgZGljdGlvbmFyeSkgewogICAgdmFyIGRpY3RMZW5ndGggPSBkaWN0aW9uYXJ5Lmxlbmd0aDsKICAgIGlmICghc3RybSAvKj09IFpfTlVMTCovIHx8ICFzdHJtLnN0YXRlIC8qPT0gWl9OVUxMKi8pIHsKICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDI7CiAgICB9CiAgICB2YXIgcyA9IHN0cm0uc3RhdGU7CiAgICB2YXIgd3JhcCA9IHMud3JhcDsKICAgIGlmICh3cmFwID09PSAyIHx8IHdyYXAgPT09IDEgJiYgcy5zdGF0dXMgIT09IElOSVRfU1RBVEUgfHwgcy5sb29rYWhlYWQpIHsKICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDI7CiAgICB9CgogICAgLyogd2hlbiB1c2luZyB6bGliIHdyYXBwZXJzLCBjb21wdXRlIEFkbGVyLTMyIGZvciBwcm92aWRlZCBkaWN0aW9uYXJ5ICovCiAgICBpZiAod3JhcCA9PT0gMSkgewogICAgICAvKiBhZGxlcjMyKHN0cm0tPmFkbGVyLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoKTsgKi8KICAgICAgc3RybS5hZGxlciA9IGFkbGVyMzIkMShzdHJtLmFkbGVyLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCAwKTsKICAgIH0KICAgIHMud3JhcCA9IDA7IC8qIGF2b2lkIGNvbXB1dGluZyBBZGxlci0zMiBpbiByZWFkX2J1ZiAqLwoKICAgIC8qIGlmIGRpY3Rpb25hcnkgd291bGQgZmlsbCB3aW5kb3csIGp1c3QgcmVwbGFjZSB0aGUgaGlzdG9yeSAqLwogICAgaWYgKGRpY3RMZW5ndGggPj0gcy53X3NpemUpIHsKICAgICAgaWYgKHdyYXAgPT09IDApIHsKICAgICAgICAvKiBhbHJlYWR5IGVtcHR5IG90aGVyd2lzZSAqLwogICAgICAgIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqLwogICAgICAgIHplcm8ocy5oZWFkKTsgLy8gRmlsbCB3aXRoIE5JTCAoPSAwKTsKICAgICAgICBzLnN0cnN0YXJ0ID0gMDsKICAgICAgICBzLmJsb2NrX3N0YXJ0ID0gMDsKICAgICAgICBzLmluc2VydCA9IDA7CiAgICAgIH0KICAgICAgLyogdXNlIHRoZSB0YWlsICovCiAgICAgIC8vIGRpY3Rpb25hcnkgPSBkaWN0aW9uYXJ5LnNsaWNlKGRpY3RMZW5ndGggLSBzLndfc2l6ZSk7CiAgICAgIHZhciB0bXBEaWN0ID0gbmV3IFVpbnQ4QXJyYXkocy53X3NpemUpOwogICAgICB0bXBEaWN0LnNldChkaWN0aW9uYXJ5LnN1YmFycmF5KGRpY3RMZW5ndGggLSBzLndfc2l6ZSwgZGljdExlbmd0aCksIDApOwogICAgICBkaWN0aW9uYXJ5ID0gdG1wRGljdDsKICAgICAgZGljdExlbmd0aCA9IHMud19zaXplOwogICAgfQogICAgLyogaW5zZXJ0IGRpY3Rpb25hcnkgaW50byB3aW5kb3cgYW5kIGhhc2ggKi8KICAgIHZhciBhdmFpbCA9IHN0cm0uYXZhaWxfaW47CiAgICB2YXIgbmV4dCA9IHN0cm0ubmV4dF9pbjsKICAgIHZhciBpbnB1dCA9IHN0cm0uaW5wdXQ7CiAgICBzdHJtLmF2YWlsX2luID0gZGljdExlbmd0aDsKICAgIHN0cm0ubmV4dF9pbiA9IDA7CiAgICBzdHJtLmlucHV0ID0gZGljdGlvbmFyeTsKICAgIGZpbGxfd2luZG93KHMpOwogICAgd2hpbGUgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkgewogICAgICB2YXIgc3RyID0gcy5zdHJzdGFydDsKICAgICAgdmFyIG4gPSBzLmxvb2thaGVhZCAtIChNSU5fTUFUQ0ggLSAxKTsKICAgICAgZG8gewogICAgICAgIC8qIFVQREFURV9IQVNIKHMsIHMtPmluc19oLCBzLT53aW5kb3dbc3RyICsgTUlOX01BVENILTFdKTsgKi8KICAgICAgICBzLmluc19oID0gSEFTSChzLCBzLmluc19oLCBzLndpbmRvd1tzdHIgKyBNSU5fTUFUQ0ggLSAxXSk7CiAgICAgICAgcy5wcmV2W3N0ciAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTsKICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzdHI7CiAgICAgICAgc3RyKys7CiAgICAgIH0gd2hpbGUgKC0tbik7CiAgICAgIHMuc3Ryc3RhcnQgPSBzdHI7CiAgICAgIHMubG9va2FoZWFkID0gTUlOX01BVENIIC0gMTsKICAgICAgZmlsbF93aW5kb3cocyk7CiAgICB9CiAgICBzLnN0cnN0YXJ0ICs9IHMubG9va2FoZWFkOwogICAgcy5ibG9ja19zdGFydCA9IHMuc3Ryc3RhcnQ7CiAgICBzLmluc2VydCA9IHMubG9va2FoZWFkOwogICAgcy5sb29rYWhlYWQgPSAwOwogICAgcy5tYXRjaF9sZW5ndGggPSBzLnByZXZfbGVuZ3RoID0gTUlOX01BVENIIC0gMTsKICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMDsKICAgIHN0cm0ubmV4dF9pbiA9IG5leHQ7CiAgICBzdHJtLmlucHV0ID0gaW5wdXQ7CiAgICBzdHJtLmF2YWlsX2luID0gYXZhaWw7CiAgICBzLndyYXAgPSB3cmFwOwogICAgcmV0dXJuIFpfT0skMzsKICB9OwogIGRlZmxhdGUkMy5kZWZsYXRlSW5pdCA9IGRlZmxhdGVJbml0OwogIGRlZmxhdGUkMy5kZWZsYXRlSW5pdDIgPSBkZWZsYXRlSW5pdDI7CiAgZGVmbGF0ZSQzLmRlZmxhdGVSZXNldCA9IGRlZmxhdGVSZXNldDsKICBkZWZsYXRlJDMuZGVmbGF0ZVJlc2V0S2VlcCA9IGRlZmxhdGVSZXNldEtlZXA7CiAgZGVmbGF0ZSQzLmRlZmxhdGVTZXRIZWFkZXIgPSBkZWZsYXRlU2V0SGVhZGVyOwogIGRlZmxhdGUkMy5kZWZsYXRlID0gZGVmbGF0ZSQyOwogIGRlZmxhdGUkMy5kZWZsYXRlRW5kID0gZGVmbGF0ZUVuZDsKICBkZWZsYXRlJDMuZGVmbGF0ZVNldERpY3Rpb25hcnkgPSBkZWZsYXRlU2V0RGljdGlvbmFyeTsKICBkZWZsYXRlJDMuZGVmbGF0ZUluZm8gPSAncGFrbyBkZWZsYXRlIChmcm9tIE5vZGVjYSBwcm9qZWN0KSc7CgogIHZhciBjb21tb24gPSB7fTsKCiAgdmFyIF9oYXMgPSBmdW5jdGlvbiBfaGFzKG9iaiwga2V5KSB7CiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTsKICB9OwogIGNvbW1vbi5hc3NpZ24gPSBmdW5jdGlvbiAob2JqIC8qZnJvbTEsIGZyb20yLCBmcm9tMywgLi4uKi8pIHsKICAgIHZhciBzb3VyY2VzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTsKICAgIHdoaWxlIChzb3VyY2VzLmxlbmd0aCkgewogICAgICB2YXIgc291cmNlID0gc291cmNlcy5zaGlmdCgpOwogICAgICBpZiAoIXNvdXJjZSkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChfdHlwZW9mJDEoc291cmNlKSAhPT0gJ29iamVjdCcpIHsKICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHNvdXJjZSArICdtdXN0IGJlIG5vbi1vYmplY3QnKTsKICAgICAgfQogICAgICBmb3IgKHZhciBwIGluIHNvdXJjZSkgewogICAgICAgIGlmIChfaGFzKHNvdXJjZSwgcCkpIHsKICAgICAgICAgIG9ialtwXSA9IHNvdXJjZVtwXTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBvYmo7CiAgfTsKCiAgLy8gSm9pbiBhcnJheSBvZiBjaHVua3MgdG8gc2luZ2xlIGFycmF5LgogIGNvbW1vbi5mbGF0dGVuQ2h1bmtzID0gZnVuY3Rpb24gKGNodW5rcykgewogICAgLy8gY2FsY3VsYXRlIGRhdGEgbGVuZ3RoCiAgICB2YXIgbGVuID0gMDsKICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2h1bmtzLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICBsZW4gKz0gY2h1bmtzW2ldLmxlbmd0aDsKICAgIH0KCiAgICAvLyBqb2luIGNodW5rcwogICAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGxlbik7CiAgICBmb3IgKHZhciBfaSA9IDAsIHBvcyA9IDAsIF9sID0gY2h1bmtzLmxlbmd0aDsgX2kgPCBfbDsgX2krKykgewogICAgICB2YXIgY2h1bmsgPSBjaHVua3NbX2ldOwogICAgICByZXN1bHQuc2V0KGNodW5rLCBwb3MpOwogICAgICBwb3MgKz0gY2h1bmsubGVuZ3RoOwogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9OwoKICB2YXIgc3RyaW5ncyQyID0ge307CgogIC8vIFF1aWNrIGNoZWNrIGlmIHdlIGNhbiB1c2UgZmFzdCBhcnJheSB0byBiaW4gc3RyaW5nIGNvbnZlcnNpb24KICAvLwogIC8vIC0gYXBwbHkoQXJyYXkpIGNhbiBmYWlsIG9uIEFuZHJvaWQgMi4yCiAgLy8gLSBhcHBseShVaW50OEFycmF5KSBjYW4gZmFpbCBvbiBpT1MgNS4xIFNhZmFyaQogIC8vCiAgdmFyIFNUUl9BUFBMWV9VSUFfT0sgPSB0cnVlOwogIHRyeSB7CiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KDEpKTsKICB9IGNhdGNoIChfXykgewogICAgU1RSX0FQUExZX1VJQV9PSyA9IGZhbHNlOwogIH0KCiAgLy8gVGFibGUgd2l0aCB1dGY4IGxlbmd0aHMgKGNhbGN1bGF0ZWQgYnkgZmlyc3QgYnl0ZSBvZiBzZXF1ZW5jZSkKICAvLyBOb3RlLCB0aGF0IDUgJiA2LWJ5dGUgdmFsdWVzIGFuZCBzb21lIDQtYnl0ZSB2YWx1ZXMgY2FuIG5vdCBiZSByZXByZXNlbnRlZCBpbiBKUywKICAvLyBiZWNhdXNlIG1heCBwb3NzaWJsZSBjb2RlcG9pbnQgaXMgMHgxMGZmZmYKICB2YXIgX3V0ZjhsZW4gPSBuZXcgVWludDhBcnJheSgyNTYpOwogIGZvciAodmFyIHEgPSAwOyBxIDwgMjU2OyBxKyspIHsKICAgIF91dGY4bGVuW3FdID0gcSA+PSAyNTIgPyA2IDogcSA+PSAyNDggPyA1IDogcSA+PSAyNDAgPyA0IDogcSA+PSAyMjQgPyAzIDogcSA+PSAxOTIgPyAyIDogMTsKICB9CiAgX3V0ZjhsZW5bMjU0XSA9IF91dGY4bGVuWzI1NF0gPSAxOyAvLyBJbnZhbGlkIHNlcXVlbmNlIHN0YXJ0CgogIC8vIGNvbnZlcnQgc3RyaW5nIHRvIGFycmF5ICh0eXBlZCwgd2hlbiBwb3NzaWJsZSkKICBzdHJpbmdzJDIuc3RyaW5nMmJ1ZiA9IGZ1bmN0aW9uIChzdHIpIHsKICAgIGlmICh0eXBlb2YgVGV4dEVuY29kZXIgPT09ICdmdW5jdGlvbicgJiYgVGV4dEVuY29kZXIucHJvdG90eXBlLmVuY29kZSkgewogICAgICByZXR1cm4gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHN0cik7CiAgICB9CiAgICB2YXIgYnVmLAogICAgICBjLAogICAgICBjMiwKICAgICAgbV9wb3MsCiAgICAgIGksCiAgICAgIHN0cl9sZW4gPSBzdHIubGVuZ3RoLAogICAgICBidWZfbGVuID0gMDsKCiAgICAvLyBjb3VudCBiaW5hcnkgc2l6ZQogICAgZm9yIChtX3BvcyA9IDA7IG1fcG9zIDwgc3RyX2xlbjsgbV9wb3MrKykgewogICAgICBjID0gc3RyLmNoYXJDb2RlQXQobV9wb3MpOwogICAgICBpZiAoKGMgJiAweGZjMDApID09PSAweGQ4MDAgJiYgbV9wb3MgKyAxIDwgc3RyX2xlbikgewogICAgICAgIGMyID0gc3RyLmNoYXJDb2RlQXQobV9wb3MgKyAxKTsKICAgICAgICBpZiAoKGMyICYgMHhmYzAwKSA9PT0gMHhkYzAwKSB7CiAgICAgICAgICBjID0gMHgxMDAwMCArIChjIC0gMHhkODAwIDw8IDEwKSArIChjMiAtIDB4ZGMwMCk7CiAgICAgICAgICBtX3BvcysrOwogICAgICAgIH0KICAgICAgfQogICAgICBidWZfbGVuICs9IGMgPCAweDgwID8gMSA6IGMgPCAweDgwMCA/IDIgOiBjIDwgMHgxMDAwMCA/IDMgOiA0OwogICAgfQoKICAgIC8vIGFsbG9jYXRlIGJ1ZmZlcgogICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYnVmX2xlbik7CgogICAgLy8gY29udmVydAogICAgZm9yIChpID0gMCwgbV9wb3MgPSAwOyBpIDwgYnVmX2xlbjsgbV9wb3MrKykgewogICAgICBjID0gc3RyLmNoYXJDb2RlQXQobV9wb3MpOwogICAgICBpZiAoKGMgJiAweGZjMDApID09PSAweGQ4MDAgJiYgbV9wb3MgKyAxIDwgc3RyX2xlbikgewogICAgICAgIGMyID0gc3RyLmNoYXJDb2RlQXQobV9wb3MgKyAxKTsKICAgICAgICBpZiAoKGMyICYgMHhmYzAwKSA9PT0gMHhkYzAwKSB7CiAgICAgICAgICBjID0gMHgxMDAwMCArIChjIC0gMHhkODAwIDw8IDEwKSArIChjMiAtIDB4ZGMwMCk7CiAgICAgICAgICBtX3BvcysrOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoYyA8IDB4ODApIHsKICAgICAgICAvKiBvbmUgYnl0ZSAqLwogICAgICAgIGJ1ZltpKytdID0gYzsKICAgICAgfSBlbHNlIGlmIChjIDwgMHg4MDApIHsKICAgICAgICAvKiB0d28gYnl0ZXMgKi8KICAgICAgICBidWZbaSsrXSA9IDB4QzAgfCBjID4+PiA2OwogICAgICAgIGJ1ZltpKytdID0gMHg4MCB8IGMgJiAweDNmOwogICAgICB9IGVsc2UgaWYgKGMgPCAweDEwMDAwKSB7CiAgICAgICAgLyogdGhyZWUgYnl0ZXMgKi8KICAgICAgICBidWZbaSsrXSA9IDB4RTAgfCBjID4+PiAxMjsKICAgICAgICBidWZbaSsrXSA9IDB4ODAgfCBjID4+PiA2ICYgMHgzZjsKICAgICAgICBidWZbaSsrXSA9IDB4ODAgfCBjICYgMHgzZjsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBmb3VyIGJ5dGVzICovCiAgICAgICAgYnVmW2krK10gPSAweGYwIHwgYyA+Pj4gMTg7CiAgICAgICAgYnVmW2krK10gPSAweDgwIHwgYyA+Pj4gMTIgJiAweDNmOwogICAgICAgIGJ1ZltpKytdID0gMHg4MCB8IGMgPj4+IDYgJiAweDNmOwogICAgICAgIGJ1ZltpKytdID0gMHg4MCB8IGMgJiAweDNmOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gYnVmOwogIH07CgogIC8vIEhlbHBlcgogIHZhciBidWYyYmluc3RyaW5nID0gZnVuY3Rpb24gYnVmMmJpbnN0cmluZyhidWYsIGxlbikgewogICAgLy8gT24gQ2hyb21lLCB0aGUgYXJndW1lbnRzIGluIGEgZnVuY3Rpb24gY2FsbCB0aGF0IGFyZSBhbGxvd2VkIGlzIGA2NTUzNGAuCiAgICAvLyBJZiB0aGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIgaXMgc21hbGxlciB0aGFuIHRoYXQsIHdlIGNhbiB1c2UgdGhpcyBvcHRpbWl6YXRpb24sCiAgICAvLyBvdGhlcndpc2Ugd2Ugd2lsbCB0YWtlIGEgc2xvd2VyIHBhdGguCiAgICBpZiAobGVuIDwgNjU1MzQpIHsKICAgICAgaWYgKGJ1Zi5zdWJhcnJheSAmJiBTVFJfQVBQTFlfVUlBX09LKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYnVmLmxlbmd0aCA9PT0gbGVuID8gYnVmIDogYnVmLnN1YmFycmF5KDAsIGxlbikpOwogICAgICB9CiAgICB9CiAgICB2YXIgcmVzdWx0ID0gJyc7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0OwogIH07CgogIC8vIGNvbnZlcnQgYXJyYXkgdG8gc3RyaW5nCiAgc3RyaW5ncyQyLmJ1ZjJzdHJpbmcgPSBmdW5jdGlvbiAoYnVmLCBtYXgpIHsKICAgIHZhciBsZW4gPSBtYXggfHwgYnVmLmxlbmd0aDsKICAgIGlmICh0eXBlb2YgVGV4dERlY29kZXIgPT09ICdmdW5jdGlvbicgJiYgVGV4dERlY29kZXIucHJvdG90eXBlLmRlY29kZSkgewogICAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJ1Zi5zdWJhcnJheSgwLCBtYXgpKTsKICAgIH0KICAgIHZhciBpLCBvdXQ7CgogICAgLy8gUmVzZXJ2ZSBtYXggcG9zc2libGUgbGVuZ3RoICgyIHdvcmRzIHBlciBjaGFyKQogICAgLy8gTkI6IGJ5IHVua25vd24gcmVhc29ucywgQXJyYXkgaXMgc2lnbmlmaWNhbnRseSBmYXN0ZXIgZm9yCiAgICAvLyAgICAgU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseSB0aGFuIFVpbnQxNkFycmF5LgogICAgdmFyIHV0ZjE2YnVmID0gbmV3IEFycmF5KGxlbiAqIDIpOwogICAgZm9yIChvdXQgPSAwLCBpID0gMDsgaSA8IGxlbjspIHsKICAgICAgdmFyIGMgPSBidWZbaSsrXTsKICAgICAgLy8gcXVpY2sgcHJvY2VzcyBhc2NpaQogICAgICBpZiAoYyA8IDB4ODApIHsKICAgICAgICB1dGYxNmJ1ZltvdXQrK10gPSBjOwogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHZhciBjX2xlbiA9IF91dGY4bGVuW2NdOwogICAgICAvLyBza2lwIDUgJiA2IGJ5dGUgY29kZXMKICAgICAgaWYgKGNfbGVuID4gNCkgewogICAgICAgIHV0ZjE2YnVmW291dCsrXSA9IDB4ZmZmZDsKICAgICAgICBpICs9IGNfbGVuIC0gMTsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgLy8gYXBwbHkgbWFzayBvbiBmaXJzdCBieXRlCiAgICAgIGMgJj0gY19sZW4gPT09IDIgPyAweDFmIDogY19sZW4gPT09IDMgPyAweDBmIDogMHgwNzsKICAgICAgLy8gam9pbiB0aGUgcmVzdAogICAgICB3aGlsZSAoY19sZW4gPiAxICYmIGkgPCBsZW4pIHsKICAgICAgICBjID0gYyA8PCA2IHwgYnVmW2krK10gJiAweDNmOwogICAgICAgIGNfbGVuLS07CiAgICAgIH0KCiAgICAgIC8vIHRlcm1pbmF0ZWQgYnkgZW5kIG9mIHN0cmluZz8KICAgICAgaWYgKGNfbGVuID4gMSkgewogICAgICAgIHV0ZjE2YnVmW291dCsrXSA9IDB4ZmZmZDsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoYyA8IDB4MTAwMDApIHsKICAgICAgICB1dGYxNmJ1ZltvdXQrK10gPSBjOwogICAgICB9IGVsc2UgewogICAgICAgIGMgLT0gMHgxMDAwMDsKICAgICAgICB1dGYxNmJ1ZltvdXQrK10gPSAweGQ4MDAgfCBjID4+IDEwICYgMHgzZmY7CiAgICAgICAgdXRmMTZidWZbb3V0KytdID0gMHhkYzAwIHwgYyAmIDB4M2ZmOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gYnVmMmJpbnN0cmluZyh1dGYxNmJ1Ziwgb3V0KTsKICB9OwoKICAvLyBDYWxjdWxhdGUgbWF4IHBvc3NpYmxlIHBvc2l0aW9uIGluIHV0ZjggYnVmZmVyLAogIC8vIHRoYXQgd2lsbCBub3QgYnJlYWsgc2VxdWVuY2UuIElmIHRoYXQncyBub3QgcG9zc2libGUKICAvLyAtICh2ZXJ5IHNtYWxsIGxpbWl0cykgcmV0dXJuIG1heCBzaXplIGFzIGlzLgogIC8vCiAgLy8gYnVmW10gLSB1dGY4IGJ5dGVzIGFycmF5CiAgLy8gbWF4ICAgLSBsZW5ndGggbGltaXQgKG1hbmRhdG9yeSk7CiAgc3RyaW5ncyQyLnV0Zjhib3JkZXIgPSBmdW5jdGlvbiAoYnVmLCBtYXgpIHsKICAgIG1heCA9IG1heCB8fCBidWYubGVuZ3RoOwogICAgaWYgKG1heCA+IGJ1Zi5sZW5ndGgpIHsKICAgICAgbWF4ID0gYnVmLmxlbmd0aDsKICAgIH0KCiAgICAvLyBnbyBiYWNrIGZyb20gbGFzdCBwb3NpdGlvbiwgdW50aWwgc3RhcnQgb2Ygc2VxdWVuY2UgZm91bmQKICAgIHZhciBwb3MgPSBtYXggLSAxOwogICAgd2hpbGUgKHBvcyA+PSAwICYmIChidWZbcG9zXSAmIDB4QzApID09PSAweDgwKSB7CiAgICAgIHBvcy0tOwogICAgfQoKICAgIC8vIFZlcnkgc21hbGwgYW5kIGJyb2tlbiBzZXF1ZW5jZSwKICAgIC8vIHJldHVybiBtYXgsIGJlY2F1c2Ugd2Ugc2hvdWxkIHJldHVybiBzb21ldGhpbmcgYW55d2F5LgogICAgaWYgKHBvcyA8IDApIHsKICAgICAgcmV0dXJuIG1heDsKICAgIH0KCiAgICAvLyBJZiB3ZSBjYW1lIHRvIHN0YXJ0IG9mIGJ1ZmZlciAtIHRoYXQgbWVhbnMgYnVmZmVyIGlzIHRvbyBzbWFsbCwKICAgIC8vIHJldHVybiBtYXggdG9vLgogICAgaWYgKHBvcyA9PT0gMCkgewogICAgICByZXR1cm4gbWF4OwogICAgfQogICAgcmV0dXJuIHBvcyArIF91dGY4bGVuW2J1Zltwb3NdXSA+IG1heCA/IHBvcyA6IG1heDsKICB9OwoKICAvLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXIKICAvLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpbgogIC8vCiAgLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICAvLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKICAvLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogIC8vCiAgLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiAgLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogIC8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKICAvLwogIC8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAgLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZQogIC8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiAgLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogIC8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiAgLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAgLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KCiAgZnVuY3Rpb24gWlN0cmVhbSQyKCkgewogICAgLyogbmV4dCBpbnB1dCBieXRlICovCiAgICB0aGlzLmlucHV0ID0gbnVsbDsgLy8gSlMgc3BlY2lmaWMsIGJlY2F1c2Ugd2UgaGF2ZSBubyBwb2ludGVycwogICAgdGhpcy5uZXh0X2luID0gMDsKICAgIC8qIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUgYXQgaW5wdXQgKi8KICAgIHRoaXMuYXZhaWxfaW4gPSAwOwogICAgLyogdG90YWwgbnVtYmVyIG9mIGlucHV0IGJ5dGVzIHJlYWQgc28gZmFyICovCiAgICB0aGlzLnRvdGFsX2luID0gMDsKICAgIC8qIG5leHQgb3V0cHV0IGJ5dGUgc2hvdWxkIGJlIHB1dCB0aGVyZSAqLwogICAgdGhpcy5vdXRwdXQgPSBudWxsOyAvLyBKUyBzcGVjaWZpYywgYmVjYXVzZSB3ZSBoYXZlIG5vIHBvaW50ZXJzCiAgICB0aGlzLm5leHRfb3V0ID0gMDsKICAgIC8qIHJlbWFpbmluZyBmcmVlIHNwYWNlIGF0IG91dHB1dCAqLwogICAgdGhpcy5hdmFpbF9vdXQgPSAwOwogICAgLyogdG90YWwgbnVtYmVyIG9mIGJ5dGVzIG91dHB1dCBzbyBmYXIgKi8KICAgIHRoaXMudG90YWxfb3V0ID0gMDsKICAgIC8qIGxhc3QgZXJyb3IgbWVzc2FnZSwgTlVMTCBpZiBubyBlcnJvciAqLwogICAgdGhpcy5tc2cgPSAnJyAvKlpfTlVMTCovOwogICAgLyogbm90IHZpc2libGUgYnkgYXBwbGljYXRpb25zICovCiAgICB0aGlzLnN0YXRlID0gbnVsbDsKICAgIC8qIGJlc3QgZ3Vlc3MgYWJvdXQgdGhlIGRhdGEgdHlwZTogYmluYXJ5IG9yIHRleHQgKi8KICAgIHRoaXMuZGF0YV90eXBlID0gMiAvKlpfVU5LTk9XTiovOwogICAgLyogYWRsZXIzMiB2YWx1ZSBvZiB0aGUgdW5jb21wcmVzc2VkIGRhdGEgKi8KICAgIHRoaXMuYWRsZXIgPSAwOwogIH0KICB2YXIgenN0cmVhbSA9IFpTdHJlYW0kMjsKCiAgdmFyIHpsaWJfZGVmbGF0ZSA9IGRlZmxhdGUkMzsKICB2YXIgdXRpbHMkMSA9IGNvbW1vbjsKICB2YXIgc3RyaW5ncyQxID0gc3RyaW5ncyQyOwogIHZhciBtc2ckMSA9IG1lc3NhZ2VzOwogIHZhciBaU3RyZWFtJDEgPSB6c3RyZWFtOwogIHZhciB0b1N0cmluZyQxID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKCiAgLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKICB2YXIgWl9OT19GTFVTSCQxID0gY29uc3RhbnRzJDEuWl9OT19GTFVTSCwKICAgIFpfU1lOQ19GTFVTSCA9IGNvbnN0YW50cyQxLlpfU1lOQ19GTFVTSCwKICAgIFpfRlVMTF9GTFVTSCA9IGNvbnN0YW50cyQxLlpfRlVMTF9GTFVTSCwKICAgIFpfRklOSVNIJDIgPSBjb25zdGFudHMkMS5aX0ZJTklTSCwKICAgIFpfT0skMiA9IGNvbnN0YW50cyQxLlpfT0ssCiAgICBaX1NUUkVBTV9FTkQkMiA9IGNvbnN0YW50cyQxLlpfU1RSRUFNX0VORCwKICAgIFpfREVGQVVMVF9DT01QUkVTU0lPTiA9IGNvbnN0YW50cyQxLlpfREVGQVVMVF9DT01QUkVTU0lPTiwKICAgIFpfREVGQVVMVF9TVFJBVEVHWSA9IGNvbnN0YW50cyQxLlpfREVGQVVMVF9TVFJBVEVHWSwKICAgIFpfREVGTEFURUQkMSA9IGNvbnN0YW50cyQxLlpfREVGTEFURUQ7CgogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCgogIC8qKgogICAqIGNsYXNzIERlZmxhdGUKICAgKgogICAqIEdlbmVyaWMgSlMtc3R5bGUgd3JhcHBlciBmb3IgemxpYiBjYWxscy4gSWYgeW91IGRvbid0IG5lZWQKICAgKiBzdHJlYW1pbmcgYmVoYXZpb3VyIC0gdXNlIG1vcmUgc2ltcGxlIGZ1bmN0aW9uczogW1tkZWZsYXRlXV0sCiAgICogW1tkZWZsYXRlUmF3XV0gYW5kIFtbZ3ppcF1dLgogICAqKi8KCiAgLyogaW50ZXJuYWwKICAgKiBEZWZsYXRlLmNodW5rcyAtPiBBcnJheQogICAqCiAgICogQ2h1bmtzIG9mIG91dHB1dCBkYXRhLCBpZiBbW0RlZmxhdGUjb25EYXRhXV0gbm90IG92ZXJyaWRkZW4uCiAgICoqLwoKICAvKioKICAgKiBEZWZsYXRlLnJlc3VsdCAtPiBVaW50OEFycmF5CiAgICoKICAgKiBDb21wcmVzc2VkIHJlc3VsdCwgZ2VuZXJhdGVkIGJ5IGRlZmF1bHQgW1tEZWZsYXRlI29uRGF0YV1dCiAgICogYW5kIFtbRGVmbGF0ZSNvbkVuZF1dIGhhbmRsZXJzLiBGaWxsZWQgYWZ0ZXIgeW91IHB1c2ggbGFzdCBjaHVuawogICAqIChjYWxsIFtbRGVmbGF0ZSNwdXNoXV0gd2l0aCBgWl9GSU5JU0hgIC8gYHRydWVgIHBhcmFtKS4KICAgKiovCgogIC8qKgogICAqIERlZmxhdGUuZXJyIC0+IE51bWJlcgogICAqCiAgICogRXJyb3IgY29kZSBhZnRlciBkZWZsYXRlIGZpbmlzaGVkLiAwIChaX09LKSBvbiBzdWNjZXNzLgogICAqIFlvdSB3aWxsIG5vdCBuZWVkIGl0IGluIHJlYWwgbGlmZSwgYmVjYXVzZSBkZWZsYXRlIGVycm9ycwogICAqIGFyZSBwb3NzaWJsZSBvbmx5IG9uIHdyb25nIG9wdGlvbnMgb3IgYmFkIGBvbkRhdGFgIC8gYG9uRW5kYAogICAqIGN1c3RvbSBoYW5kbGVycy4KICAgKiovCgogIC8qKgogICAqIERlZmxhdGUubXNnIC0+IFN0cmluZwogICAqCiAgICogRXJyb3IgbWVzc2FnZSwgaWYgW1tEZWZsYXRlLmVycl1dICE9IDAKICAgKiovCgogIC8qKgogICAqIG5ldyBEZWZsYXRlKG9wdGlvbnMpCiAgICogLSBvcHRpb25zIChPYmplY3QpOiB6bGliIGRlZmxhdGUgb3B0aW9ucy4KICAgKgogICAqIENyZWF0ZXMgbmV3IGRlZmxhdG9yIGluc3RhbmNlIHdpdGggc3BlY2lmaWVkIHBhcmFtcy4gVGhyb3dzIGV4Y2VwdGlvbgogICAqIG9uIGJhZCBwYXJhbXMuIFN1cHBvcnRlZCBvcHRpb25zOgogICAqCiAgICogLSBgbGV2ZWxgCiAgICogLSBgd2luZG93Qml0c2AKICAgKiAtIGBtZW1MZXZlbGAKICAgKiAtIGBzdHJhdGVneWAKICAgKiAtIGBkaWN0aW9uYXJ5YAogICAqCiAgICogW2h0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZF0oaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkKQogICAqIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZXNlLgogICAqCiAgICogQWRkaXRpb25hbCBvcHRpb25zLCBmb3IgaW50ZXJuYWwgbmVlZHM6CiAgICoKICAgKiAtIGBjaHVua1NpemVgIC0gc2l6ZSBvZiBnZW5lcmF0ZWQgZGF0YSBjaHVua3MgKDE2SyBieSBkZWZhdWx0KQogICAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gZG8gcmF3IGRlZmxhdGUKICAgKiAtIGBnemlwYCAoQm9vbGVhbikgLSBjcmVhdGUgZ3ppcCB3cmFwcGVyCiAgICogLSBgaGVhZGVyYCAoT2JqZWN0KSAtIGN1c3RvbSBoZWFkZXIgZm9yIGd6aXAKICAgKiAgIC0gYHRleHRgIChCb29sZWFuKSAtIHRydWUgaWYgY29tcHJlc3NlZCBkYXRhIGJlbGlldmVkIHRvIGJlIHRleHQKICAgKiAgIC0gYHRpbWVgIChOdW1iZXIpIC0gbW9kaWZpY2F0aW9uIHRpbWUsIHVuaXggdGltZXN0YW1wCiAgICogICAtIGBvc2AgKE51bWJlcikgLSBvcGVyYXRpb24gc3lzdGVtIGNvZGUKICAgKiAgIC0gYGV4dHJhYCAoQXJyYXkpIC0gYXJyYXkgb2YgYnl0ZXMgd2l0aCBleHRyYSBkYXRhIChtYXggNjU1MzYpCiAgICogICAtIGBuYW1lYCAoU3RyaW5nKSAtIGZpbGUgbmFtZSAoYmluYXJ5IHN0cmluZykKICAgKiAgIC0gYGNvbW1lbnRgIChTdHJpbmcpIC0gY29tbWVudCAoYmluYXJ5IHN0cmluZykKICAgKiAgIC0gYGhjcmNgIChCb29sZWFuKSAtIHRydWUgaWYgaGVhZGVyIGNyYyBzaG91bGQgYmUgYWRkZWQKICAgKgogICAqICMjIyMjIEV4YW1wbGU6CiAgICoKICAgKiBgYGBqYXZhc2NyaXB0CiAgICogY29uc3QgcGFrbyA9IHJlcXVpcmUoJ3Bha28nKQogICAqICAgLCBjaHVuazEgPSBuZXcgVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKQogICAqICAgLCBjaHVuazIgPSBuZXcgVWludDhBcnJheShbMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTldKTsKICAgKgogICAqIGNvbnN0IGRlZmxhdGUgPSBuZXcgcGFrby5EZWZsYXRlKHsgbGV2ZWw6IDN9KTsKICAgKgogICAqIGRlZmxhdGUucHVzaChjaHVuazEsIGZhbHNlKTsKICAgKiBkZWZsYXRlLnB1c2goY2h1bmsyLCB0cnVlKTsgIC8vIHRydWUgLT4gbGFzdCBjaHVuawogICAqCiAgICogaWYgKGRlZmxhdGUuZXJyKSB7IHRocm93IG5ldyBFcnJvcihkZWZsYXRlLmVycik7IH0KICAgKgogICAqIGNvbnNvbGUubG9nKGRlZmxhdGUucmVzdWx0KTsKICAgKiBgYGAKICAgKiovCiAgZnVuY3Rpb24gRGVmbGF0ZSQxKG9wdGlvbnMpIHsKICAgIHRoaXMub3B0aW9ucyA9IHV0aWxzJDEuYXNzaWduKHsKICAgICAgbGV2ZWw6IFpfREVGQVVMVF9DT01QUkVTU0lPTiwKICAgICAgbWV0aG9kOiBaX0RFRkxBVEVEJDEsCiAgICAgIGNodW5rU2l6ZTogMTYzODQsCiAgICAgIHdpbmRvd0JpdHM6IDE1LAogICAgICBtZW1MZXZlbDogOCwKICAgICAgc3RyYXRlZ3k6IFpfREVGQVVMVF9TVFJBVEVHWQogICAgfSwgb3B0aW9ucyB8fCB7fSk7CiAgICB2YXIgb3B0ID0gdGhpcy5vcHRpb25zOwogICAgaWYgKG9wdC5yYXcgJiYgb3B0LndpbmRvd0JpdHMgPiAwKSB7CiAgICAgIG9wdC53aW5kb3dCaXRzID0gLW9wdC53aW5kb3dCaXRzOwogICAgfSBlbHNlIGlmIChvcHQuZ3ppcCAmJiBvcHQud2luZG93Qml0cyA+IDAgJiYgb3B0LndpbmRvd0JpdHMgPCAxNikgewogICAgICBvcHQud2luZG93Qml0cyArPSAxNjsKICAgIH0KICAgIHRoaXMuZXJyID0gMDsgLy8gZXJyb3IgY29kZSwgaWYgaGFwcGVucyAoMCA9IFpfT0spCiAgICB0aGlzLm1zZyA9ICcnOyAvLyBlcnJvciBtZXNzYWdlCiAgICB0aGlzLmVuZGVkID0gZmFsc2U7IC8vIHVzZWQgdG8gYXZvaWQgbXVsdGlwbGUgb25FbmQoKSBjYWxscwogICAgdGhpcy5jaHVua3MgPSBbXTsgLy8gY2h1bmtzIG9mIGNvbXByZXNzZWQgZGF0YQoKICAgIHRoaXMuc3RybSA9IG5ldyBaU3RyZWFtJDEoKTsKICAgIHRoaXMuc3RybS5hdmFpbF9vdXQgPSAwOwogICAgdmFyIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlSW5pdDIodGhpcy5zdHJtLCBvcHQubGV2ZWwsIG9wdC5tZXRob2QsIG9wdC53aW5kb3dCaXRzLCBvcHQubWVtTGV2ZWwsIG9wdC5zdHJhdGVneSk7CiAgICBpZiAoc3RhdHVzICE9PSBaX09LJDIpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyQxW3N0YXR1c10pOwogICAgfQogICAgaWYgKG9wdC5oZWFkZXIpIHsKICAgICAgemxpYl9kZWZsYXRlLmRlZmxhdGVTZXRIZWFkZXIodGhpcy5zdHJtLCBvcHQuaGVhZGVyKTsKICAgIH0KICAgIGlmIChvcHQuZGljdGlvbmFyeSkgewogICAgICB2YXIgZGljdDsKICAgICAgLy8gQ29udmVydCBkYXRhIGlmIG5lZWRlZAogICAgICBpZiAodHlwZW9mIG9wdC5kaWN0aW9uYXJ5ID09PSAnc3RyaW5nJykgewogICAgICAgIC8vIElmIHdlIG5lZWQgdG8gY29tcHJlc3MgdGV4dCwgY2hhbmdlIGVuY29kaW5nIHRvIHV0ZjguCiAgICAgICAgZGljdCA9IHN0cmluZ3MkMS5zdHJpbmcyYnVmKG9wdC5kaWN0aW9uYXJ5KTsKICAgICAgfSBlbHNlIGlmICh0b1N0cmluZyQxLmNhbGwob3B0LmRpY3Rpb25hcnkpID09PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nKSB7CiAgICAgICAgZGljdCA9IG5ldyBVaW50OEFycmF5KG9wdC5kaWN0aW9uYXJ5KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkaWN0ID0gb3B0LmRpY3Rpb25hcnk7CiAgICAgIH0KICAgICAgc3RhdHVzID0gemxpYl9kZWZsYXRlLmRlZmxhdGVTZXREaWN0aW9uYXJ5KHRoaXMuc3RybSwgZGljdCk7CiAgICAgIGlmIChzdGF0dXMgIT09IFpfT0skMikgewogICAgICAgIHRocm93IG5ldyBFcnJvcihtc2ckMVtzdGF0dXNdKTsKICAgICAgfQogICAgICB0aGlzLl9kaWN0X3NldCA9IHRydWU7CiAgICB9CiAgfQoKICAvKioKICAgKiBEZWZsYXRlI3B1c2goZGF0YVssIGZsdXNoX21vZGVdKSAtPiBCb29sZWFuCiAgICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGEuIFN0cmluZ3Mgd2lsbCBiZQogICAqICAgY29udmVydGVkIHRvIHV0ZjggYnl0ZSBzZXF1ZW5jZS4KICAgKiAtIGZsdXNoX21vZGUgKE51bWJlcnxCb29sZWFuKTogMC4uNiBmb3IgY29ycmVzcG9uZGluZyBaX05PX0ZMVVNILi5aX1RSRUUgbW9kZXMuCiAgICogICBTZWUgY29uc3RhbnRzLiBTa2lwcGVkIG9yIGBmYWxzZWAgbWVhbnMgWl9OT19GTFVTSCwgYHRydWVgIG1lYW5zIFpfRklOSVNILgogICAqCiAgICogU2VuZHMgaW5wdXQgZGF0YSB0byBkZWZsYXRlIHBpcGUsIGdlbmVyYXRpbmcgW1tEZWZsYXRlI29uRGF0YV1dIGNhbGxzIHdpdGgKICAgKiBuZXcgY29tcHJlc3NlZCBjaHVua3MuIFJldHVybnMgYHRydWVgIG9uIHN1Y2Nlc3MuIFRoZSBsYXN0IGRhdGEgYmxvY2sgbXVzdAogICAqIGhhdmUgYGZsdXNoX21vZGVgIFpfRklOSVNIIChvciBgdHJ1ZWApLiBUaGF0IHdpbGwgZmx1c2ggaW50ZXJuYWwgcGVuZGluZwogICAqIGJ1ZmZlcnMgYW5kIGNhbGwgW1tEZWZsYXRlI29uRW5kXV0uCiAgICoKICAgKiBPbiBmYWlsIGNhbGwgW1tEZWZsYXRlI29uRW5kXV0gd2l0aCBlcnJvciBjb2RlIGFuZCByZXR1cm4gZmFsc2UuCiAgICoKICAgKiAjIyMjIyBFeGFtcGxlCiAgICoKICAgKiBgYGBqYXZhc2NyaXB0CiAgICogcHVzaChjaHVuaywgZmFsc2UpOyAvLyBwdXNoIG9uZSBvZiBkYXRhIGNodW5rcwogICAqIC4uLgogICAqIHB1c2goY2h1bmssIHRydWUpOyAgLy8gcHVzaCBsYXN0IGNodW5rCiAgICogYGBgCiAgICoqLwogIERlZmxhdGUkMS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChkYXRhLCBmbHVzaF9tb2RlKSB7CiAgICB2YXIgc3RybSA9IHRoaXMuc3RybTsKICAgIHZhciBjaHVua1NpemUgPSB0aGlzLm9wdGlvbnMuY2h1bmtTaXplOwogICAgdmFyIHN0YXR1cywgX2ZsdXNoX21vZGU7CiAgICBpZiAodGhpcy5lbmRlZCkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoZmx1c2hfbW9kZSA9PT0gfn5mbHVzaF9tb2RlKSBfZmx1c2hfbW9kZSA9IGZsdXNoX21vZGU7ZWxzZSBfZmx1c2hfbW9kZSA9IGZsdXNoX21vZGUgPT09IHRydWUgPyBaX0ZJTklTSCQyIDogWl9OT19GTFVTSCQxOwoKICAgIC8vIENvbnZlcnQgZGF0YSBpZiBuZWVkZWQKICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHsKICAgICAgLy8gSWYgd2UgbmVlZCB0byBjb21wcmVzcyB0ZXh0LCBjaGFuZ2UgZW5jb2RpbmcgdG8gdXRmOC4KICAgICAgc3RybS5pbnB1dCA9IHN0cmluZ3MkMS5zdHJpbmcyYnVmKGRhdGEpOwogICAgfSBlbHNlIGlmICh0b1N0cmluZyQxLmNhbGwoZGF0YSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHsKICAgICAgc3RybS5pbnB1dCA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgc3RybS5pbnB1dCA9IGRhdGE7CiAgICB9CiAgICBzdHJtLm5leHRfaW4gPSAwOwogICAgc3RybS5hdmFpbF9pbiA9IHN0cm0uaW5wdXQubGVuZ3RoOwogICAgZm9yICg7OykgewogICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHsKICAgICAgICBzdHJtLm91dHB1dCA9IG5ldyBVaW50OEFycmF5KGNodW5rU2l6ZSk7CiAgICAgICAgc3RybS5uZXh0X291dCA9IDA7CiAgICAgICAgc3RybS5hdmFpbF9vdXQgPSBjaHVua1NpemU7CiAgICAgIH0KCiAgICAgIC8vIE1ha2Ugc3VyZSBhdmFpbF9vdXQgPiA2IHRvIGF2b2lkIHJlcGVhdGluZyBtYXJrZXJzCiAgICAgIGlmICgoX2ZsdXNoX21vZGUgPT09IFpfU1lOQ19GTFVTSCB8fCBfZmx1c2hfbW9kZSA9PT0gWl9GVUxMX0ZMVVNIKSAmJiBzdHJtLmF2YWlsX291dCA8PSA2KSB7CiAgICAgICAgdGhpcy5vbkRhdGEoc3RybS5vdXRwdXQuc3ViYXJyYXkoMCwgc3RybS5uZXh0X291dCkpOwogICAgICAgIHN0cm0uYXZhaWxfb3V0ID0gMDsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzdGF0dXMgPSB6bGliX2RlZmxhdGUuZGVmbGF0ZShzdHJtLCBfZmx1c2hfbW9kZSk7CgogICAgICAvLyBFbmRlZCA9PiBmbHVzaCBhbmQgZmluaXNoCiAgICAgIGlmIChzdGF0dXMgPT09IFpfU1RSRUFNX0VORCQyKSB7CiAgICAgICAgaWYgKHN0cm0ubmV4dF9vdXQgPiAwKSB7CiAgICAgICAgICB0aGlzLm9uRGF0YShzdHJtLm91dHB1dC5zdWJhcnJheSgwLCBzdHJtLm5leHRfb3V0KSk7CiAgICAgICAgfQogICAgICAgIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlRW5kKHRoaXMuc3RybSk7CiAgICAgICAgdGhpcy5vbkVuZChzdGF0dXMpOwogICAgICAgIHRoaXMuZW5kZWQgPSB0cnVlOwogICAgICAgIHJldHVybiBzdGF0dXMgPT09IFpfT0skMjsKICAgICAgfQoKICAgICAgLy8gRmx1c2ggaWYgb3V0IGJ1ZmZlciBmdWxsCiAgICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHRoaXMub25EYXRhKHN0cm0ub3V0cHV0KTsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgLy8gRmx1c2ggaWYgcmVxdWVzdGVkIGFuZCBoYXMgZGF0YQogICAgICBpZiAoX2ZsdXNoX21vZGUgPiAwICYmIHN0cm0ubmV4dF9vdXQgPiAwKSB7CiAgICAgICAgdGhpcy5vbkRhdGEoc3RybS5vdXRwdXQuc3ViYXJyYXkoMCwgc3RybS5uZXh0X291dCkpOwogICAgICAgIHN0cm0uYXZhaWxfb3V0ID0gMDsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoc3RybS5hdmFpbF9pbiA9PT0gMCkgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9OwoKICAvKioKICAgKiBEZWZsYXRlI29uRGF0YShjaHVuaykgLT4gVm9pZAogICAqIC0gY2h1bmsgKFVpbnQ4QXJyYXkpOiBvdXRwdXQgZGF0YS4KICAgKgogICAqIEJ5IGRlZmF1bHQsIHN0b3JlcyBkYXRhIGJsb2NrcyBpbiBgY2h1bmtzW11gIHByb3BlcnR5IGFuZCBnbHVlCiAgICogdGhvc2UgaW4gYG9uRW5kYC4gT3ZlcnJpZGUgdGhpcyBoYW5kbGVyLCBpZiB5b3UgbmVlZCBhbm90aGVyIGJlaGF2aW91ci4KICAgKiovCiAgRGVmbGF0ZSQxLnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbiAoY2h1bmspIHsKICAgIHRoaXMuY2h1bmtzLnB1c2goY2h1bmspOwogIH07CgogIC8qKgogICAqIERlZmxhdGUjb25FbmQoc3RhdHVzKSAtPiBWb2lkCiAgICogLSBzdGF0dXMgKE51bWJlcik6IGRlZmxhdGUgc3RhdHVzLiAwIChaX09LKSBvbiBzdWNjZXNzLAogICAqICAgb3RoZXIgaWYgbm90LgogICAqCiAgICogQ2FsbGVkIG9uY2UgYWZ0ZXIgeW91IHRlbGwgZGVmbGF0ZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0gaXMKICAgKiBjb21wbGV0ZSAoWl9GSU5JU0gpLiBCeSBkZWZhdWx0IC0gam9pbiBjb2xsZWN0ZWQgY2h1bmtzLAogICAqIGZyZWUgbWVtb3J5IGFuZCBmaWxsIGByZXN1bHRzYCAvIGBlcnJgIHByb3BlcnRpZXMuCiAgICoqLwogIERlZmxhdGUkMS5wcm90b3R5cGUub25FbmQgPSBmdW5jdGlvbiAoc3RhdHVzKSB7CiAgICAvLyBPbiBzdWNjZXNzIC0gam9pbgogICAgaWYgKHN0YXR1cyA9PT0gWl9PSyQyKSB7CiAgICAgIHRoaXMucmVzdWx0ID0gdXRpbHMkMS5mbGF0dGVuQ2h1bmtzKHRoaXMuY2h1bmtzKTsKICAgIH0KICAgIHRoaXMuY2h1bmtzID0gW107CiAgICB0aGlzLmVyciA9IHN0YXR1czsKICAgIHRoaXMubXNnID0gdGhpcy5zdHJtLm1zZzsKICB9OwoKICAvKioKICAgKiBkZWZsYXRlKGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheQogICAqIC0gZGF0YSAoVWludDhBcnJheXxTdHJpbmcpOiBpbnB1dCBkYXRhIHRvIGNvbXByZXNzLgogICAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBkZWZsYXRlIG9wdGlvbnMuCiAgICoKICAgKiBDb21wcmVzcyBgZGF0YWAgd2l0aCBkZWZsYXRlIGFsZ29yaXRobSBhbmQgYG9wdGlvbnNgLgogICAqCiAgICogU3VwcG9ydGVkIG9wdGlvbnMgYXJlOgogICAqCiAgICogLSBsZXZlbAogICAqIC0gd2luZG93Qml0cwogICAqIC0gbWVtTGV2ZWwKICAgKiAtIHN0cmF0ZWd5CiAgICogLSBkaWN0aW9uYXJ5CiAgICoKICAgKiBbaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkXShodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWQpCiAgICogZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlc2UuCiAgICoKICAgKiBTdWdhciAob3B0aW9ucyk6CiAgICoKICAgKiAtIGByYXdgIChCb29sZWFuKSAtIHNheSB0aGF0IHdlIHdvcmsgd2l0aCByYXcgc3RyZWFtLCBpZiB5b3UgZG9uJ3Qgd2lzaCB0byBzcGVjaWZ5CiAgICogICBuZWdhdGl2ZSB3aW5kb3dCaXRzIGltcGxpY2l0bHkuCiAgICoKICAgKiAjIyMjIyBFeGFtcGxlOgogICAqCiAgICogYGBgamF2YXNjcmlwdAogICAqIGNvbnN0IHBha28gPSByZXF1aXJlKCdwYWtvJykKICAgKiBjb25zdCBkYXRhID0gbmV3IFVpbnQ4QXJyYXkoWzEsMiwzLDQsNSw2LDcsOCw5XSk7CiAgICoKICAgKiBjb25zb2xlLmxvZyhwYWtvLmRlZmxhdGUoZGF0YSkpOwogICAqIGBgYAogICAqKi8KICBmdW5jdGlvbiBkZWZsYXRlJDEoaW5wdXQsIG9wdGlvbnMpIHsKICAgIHZhciBkZWZsYXRvciA9IG5ldyBEZWZsYXRlJDEob3B0aW9ucyk7CiAgICBkZWZsYXRvci5wdXNoKGlucHV0LCB0cnVlKTsKCiAgICAvLyBUaGF0IHdpbGwgbmV2ZXIgaGFwcGVucywgaWYgeW91IGRvbid0IGNoZWF0IHdpdGggb3B0aW9ucyA6KQogICAgaWYgKGRlZmxhdG9yLmVycikgewogICAgICB0aHJvdyBkZWZsYXRvci5tc2cgfHwgbXNnJDFbZGVmbGF0b3IuZXJyXTsKICAgIH0KICAgIHJldHVybiBkZWZsYXRvci5yZXN1bHQ7CiAgfQoKICAvKioKICAgKiBkZWZsYXRlUmF3KGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheQogICAqIC0gZGF0YSAoVWludDhBcnJheXxTdHJpbmcpOiBpbnB1dCBkYXRhIHRvIGNvbXByZXNzLgogICAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBkZWZsYXRlIG9wdGlvbnMuCiAgICoKICAgKiBUaGUgc2FtZSBhcyBbW2RlZmxhdGVdXSwgYnV0IGNyZWF0ZXMgcmF3IGRhdGEsIHdpdGhvdXQgd3JhcHBlcgogICAqIChoZWFkZXIgYW5kIGFkbGVyMzIgY3JjKS4KICAgKiovCiAgZnVuY3Rpb24gZGVmbGF0ZVJhdyQxKGlucHV0LCBvcHRpb25zKSB7CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMucmF3ID0gdHJ1ZTsKICAgIHJldHVybiBkZWZsYXRlJDEoaW5wdXQsIG9wdGlvbnMpOwogIH0KCiAgLyoqCiAgICogZ3ppcChkYXRhWywgb3B0aW9uc10pIC0+IFVpbnQ4QXJyYXkKICAgKiAtIGRhdGEgKFVpbnQ4QXJyYXl8U3RyaW5nKTogaW5wdXQgZGF0YSB0byBjb21wcmVzcy4KICAgKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLgogICAqCiAgICogVGhlIHNhbWUgYXMgW1tkZWZsYXRlXV0sIGJ1dCBjcmVhdGUgZ3ppcCB3cmFwcGVyIGluc3RlYWQgb2YKICAgKiBkZWZsYXRlIG9uZS4KICAgKiovCiAgZnVuY3Rpb24gZ3ppcCQxKGlucHV0LCBvcHRpb25zKSB7CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMuZ3ppcCA9IHRydWU7CiAgICByZXR1cm4gZGVmbGF0ZSQxKGlucHV0LCBvcHRpb25zKTsKICB9CiAgZGVmbGF0ZSQ0LkRlZmxhdGUgPSBEZWZsYXRlJDE7CiAgZGVmbGF0ZSQ0LmRlZmxhdGUgPSBkZWZsYXRlJDE7CiAgZGVmbGF0ZSQ0LmRlZmxhdGVSYXcgPSBkZWZsYXRlUmF3JDE7CiAgZGVmbGF0ZSQ0Lmd6aXAgPSBnemlwJDE7CiAgZGVmbGF0ZSQ0LmNvbnN0YW50cyA9IGNvbnN0YW50cyQxOwoKICB2YXIgaW5mbGF0ZSQ0ID0ge307CgogIHZhciBpbmZsYXRlJDMgPSB7fTsKCiAgLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyCiAgLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW4KICAvLwogIC8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkCiAgLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiAgLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KICAvLwogIC8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAogIC8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQKICAvLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAgLy8KICAvLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdAogIC8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKICAvLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogIC8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC4KICAvLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogIC8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgogIC8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgogIC8vIFNlZSBzdGF0ZSBkZWZzIGZyb20gaW5mbGF0ZS5qcwogIHZhciBCQUQkMSA9IDMwOyAvKiBnb3QgYSBkYXRhIGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovCiAgdmFyIFRZUEUkMSA9IDEyOyAvKiBpOiB3YWl0aW5nIGZvciB0eXBlIGJpdHMsIGluY2x1ZGluZyBsYXN0LWZsYWcgYml0ICovCgogIC8qCiAgICAgRGVjb2RlIGxpdGVyYWwsIGxlbmd0aCwgYW5kIGRpc3RhbmNlIGNvZGVzIGFuZCB3cml0ZSBvdXQgdGhlIHJlc3VsdGluZwogICAgIGxpdGVyYWwgYW5kIG1hdGNoIGJ5dGVzIHVudGlsIGVpdGhlciBub3QgZW5vdWdoIGlucHV0IG9yIG91dHB1dCBpcwogICAgIGF2YWlsYWJsZSwgYW4gZW5kLW9mLWJsb2NrIGlzIGVuY291bnRlcmVkLCBvciBhIGRhdGEgZXJyb3IgaXMgZW5jb3VudGVyZWQuCiAgICAgV2hlbiBsYXJnZSBlbm91Z2ggaW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIGFyZSBzdXBwbGllZCB0byBpbmZsYXRlKCksIGZvcgogICAgIGV4YW1wbGUsIGEgMTZLIGlucHV0IGJ1ZmZlciBhbmQgYSA2NEsgb3V0cHV0IGJ1ZmZlciwgbW9yZSB0aGFuIDk1JSBvZiB0aGUKICAgICBpbmZsYXRlIGV4ZWN1dGlvbiB0aW1lIGlzIHNwZW50IGluIHRoaXMgcm91dGluZS4KCiAgICAgRW50cnkgYXNzdW1wdGlvbnM6CgogICAgICAgICAgc3RhdGUubW9kZSA9PT0gTEVOCiAgICAgICAgICBzdHJtLmF2YWlsX2luID49IDYKICAgICAgICAgIHN0cm0uYXZhaWxfb3V0ID49IDI1OAogICAgICAgICAgc3RhcnQgPj0gc3RybS5hdmFpbF9vdXQKICAgICAgICAgIHN0YXRlLmJpdHMgPCA4CgogICAgIE9uIHJldHVybiwgc3RhdGUubW9kZSBpcyBvbmUgb2Y6CgogICAgICAgICAgTEVOIC0tIHJhbiBvdXQgb2YgZW5vdWdoIG91dHB1dCBzcGFjZSBvciBlbm91Z2ggYXZhaWxhYmxlIGlucHV0CiAgICAgICAgICBUWVBFIC0tIHJlYWNoZWQgZW5kIG9mIGJsb2NrIGNvZGUsIGluZmxhdGUoKSB0byBpbnRlcnByZXQgbmV4dCBibG9jawogICAgICAgICAgQkFEIC0tIGVycm9yIGluIGJsb2NrIGRhdGEKCiAgICAgTm90ZXM6CgogICAgICAtIFRoZSBtYXhpbXVtIGlucHV0IGJpdHMgdXNlZCBieSBhIGxlbmd0aC9kaXN0YW5jZSBwYWlyIGlzIDE1IGJpdHMgZm9yIHRoZQogICAgICAgIGxlbmd0aCBjb2RlLCA1IGJpdHMgZm9yIHRoZSBsZW5ndGggZXh0cmEsIDE1IGJpdHMgZm9yIHRoZSBkaXN0YW5jZSBjb2RlLAogICAgICAgIGFuZCAxMyBiaXRzIGZvciB0aGUgZGlzdGFuY2UgZXh0cmEuICBUaGlzIHRvdGFscyA0OCBiaXRzLCBvciBzaXggYnl0ZXMuCiAgICAgICAgVGhlcmVmb3JlIGlmIHN0cm0uYXZhaWxfaW4gPj0gNiwgdGhlbiB0aGVyZSBpcyBlbm91Z2ggaW5wdXQgdG8gYXZvaWQKICAgICAgICBjaGVja2luZyBmb3IgYXZhaWxhYmxlIGlucHV0IHdoaWxlIGRlY29kaW5nLgoKICAgICAgLSBUaGUgbWF4aW11bSBieXRlcyB0aGF0IGEgc2luZ2xlIGxlbmd0aC9kaXN0YW5jZSBwYWlyIGNhbiBvdXRwdXQgaXMgMjU4CiAgICAgICAgYnl0ZXMsIHdoaWNoIGlzIHRoZSBtYXhpbXVtIGxlbmd0aCB0aGF0IGNhbiBiZSBjb2RlZC4gIGluZmxhdGVfZmFzdCgpCiAgICAgICAgcmVxdWlyZXMgc3RybS5hdmFpbF9vdXQgPj0gMjU4IGZvciBlYWNoIGxvb3AgdG8gYXZvaWQgY2hlY2tpbmcgZm9yCiAgICAgICAgb3V0cHV0IHNwYWNlLgogICAqLwogIHZhciBpbmZmYXN0ID0gZnVuY3Rpb24gaW5mbGF0ZV9mYXN0KHN0cm0sIHN0YXJ0KSB7CiAgICB2YXIgX2luOyAvKiBsb2NhbCBzdHJtLmlucHV0ICovCiAgICB2YXIgbGFzdDsgLyogaGF2ZSBlbm91Z2ggaW5wdXQgd2hpbGUgaW4gPCBsYXN0ICovCiAgICB2YXIgX291dDsgLyogbG9jYWwgc3RybS5vdXRwdXQgKi8KICAgIHZhciBiZWc7IC8qIGluZmxhdGUoKSdzIGluaXRpYWwgc3RybS5vdXRwdXQgKi8KICAgIHZhciBlbmQ7IC8qIHdoaWxlIG91dCA8IGVuZCwgZW5vdWdoIHNwYWNlIGF2YWlsYWJsZSAqLwogICAgLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1QKICAgIHZhciBkbWF4OyAvKiBtYXhpbXVtIGRpc3RhbmNlIGZyb20gemxpYiBoZWFkZXIgKi8KICAgIC8vI2VuZGlmCiAgICB2YXIgd3NpemU7IC8qIHdpbmRvdyBzaXplIG9yIHplcm8gaWYgbm90IHVzaW5nIHdpbmRvdyAqLwogICAgdmFyIHdoYXZlOyAvKiB2YWxpZCBieXRlcyBpbiB0aGUgd2luZG93ICovCiAgICB2YXIgd25leHQ7IC8qIHdpbmRvdyB3cml0ZSBpbmRleCAqLwogICAgLy8gVXNlIGBzX3dpbmRvd2AgaW5zdGVhZCBgd2luZG93YCwgYXZvaWQgY29uZmxpY3Qgd2l0aCBpbnN0cnVtZW50YXRpb24gdG9vbHMKICAgIHZhciBzX3dpbmRvdzsgLyogYWxsb2NhdGVkIHNsaWRpbmcgd2luZG93LCBpZiB3c2l6ZSAhPSAwICovCiAgICB2YXIgaG9sZDsgLyogbG9jYWwgc3RybS5ob2xkICovCiAgICB2YXIgYml0czsgLyogbG9jYWwgc3RybS5iaXRzICovCiAgICB2YXIgbGNvZGU7IC8qIGxvY2FsIHN0cm0ubGVuY29kZSAqLwogICAgdmFyIGRjb2RlOyAvKiBsb2NhbCBzdHJtLmRpc3Rjb2RlICovCiAgICB2YXIgbG1hc2s7IC8qIG1hc2sgZm9yIGZpcnN0IGxldmVsIG9mIGxlbmd0aCBjb2RlcyAqLwogICAgdmFyIGRtYXNrOyAvKiBtYXNrIGZvciBmaXJzdCBsZXZlbCBvZiBkaXN0YW5jZSBjb2RlcyAqLwogICAgdmFyIGhlcmU7IC8qIHJldHJpZXZlZCB0YWJsZSBlbnRyeSAqLwogICAgdmFyIG9wOyAvKiBjb2RlIGJpdHMsIG9wZXJhdGlvbiwgZXh0cmEgYml0cywgb3IgKi8KICAgIC8qICB3aW5kb3cgcG9zaXRpb24sIHdpbmRvdyBieXRlcyB0byBjb3B5ICovCiAgICB2YXIgbGVuOyAvKiBtYXRjaCBsZW5ndGgsIHVudXNlZCBieXRlcyAqLwogICAgdmFyIGRpc3Q7IC8qIG1hdGNoIGRpc3RhbmNlICovCiAgICB2YXIgZnJvbTsgLyogd2hlcmUgdG8gY29weSBtYXRjaCBmcm9tICovCiAgICB2YXIgZnJvbV9zb3VyY2U7CiAgICB2YXIgaW5wdXQsIG91dHB1dDsgLy8gSlMgc3BlY2lmaWMsIGJlY2F1c2Ugd2UgaGF2ZSBubyBwb2ludGVycwoKICAgIC8qIGNvcHkgc3RhdGUgdG8gbG9jYWwgdmFyaWFibGVzICovCiAgICB2YXIgc3RhdGUgPSBzdHJtLnN0YXRlOwogICAgLy9oZXJlID0gc3RhdGUuaGVyZTsKICAgIF9pbiA9IHN0cm0ubmV4dF9pbjsKICAgIGlucHV0ID0gc3RybS5pbnB1dDsKICAgIGxhc3QgPSBfaW4gKyAoc3RybS5hdmFpbF9pbiAtIDUpOwogICAgX291dCA9IHN0cm0ubmV4dF9vdXQ7CiAgICBvdXRwdXQgPSBzdHJtLm91dHB1dDsKICAgIGJlZyA9IF9vdXQgLSAoc3RhcnQgLSBzdHJtLmF2YWlsX291dCk7CiAgICBlbmQgPSBfb3V0ICsgKHN0cm0uYXZhaWxfb3V0IC0gMjU3KTsKICAgIC8vI2lmZGVmIElORkxBVEVfU1RSSUNUCiAgICBkbWF4ID0gc3RhdGUuZG1heDsKICAgIC8vI2VuZGlmCiAgICB3c2l6ZSA9IHN0YXRlLndzaXplOwogICAgd2hhdmUgPSBzdGF0ZS53aGF2ZTsKICAgIHduZXh0ID0gc3RhdGUud25leHQ7CiAgICBzX3dpbmRvdyA9IHN0YXRlLndpbmRvdzsKICAgIGhvbGQgPSBzdGF0ZS5ob2xkOwogICAgYml0cyA9IHN0YXRlLmJpdHM7CiAgICBsY29kZSA9IHN0YXRlLmxlbmNvZGU7CiAgICBkY29kZSA9IHN0YXRlLmRpc3Rjb2RlOwogICAgbG1hc2sgPSAoMSA8PCBzdGF0ZS5sZW5iaXRzKSAtIDE7CiAgICBkbWFzayA9ICgxIDw8IHN0YXRlLmRpc3RiaXRzKSAtIDE7CgogICAgLyogZGVjb2RlIGxpdGVyYWxzIGFuZCBsZW5ndGgvZGlzdGFuY2VzIHVudGlsIGVuZC1vZi1ibG9jayBvciBub3QgZW5vdWdoCiAgICAgICBpbnB1dCBkYXRhIG9yIG91dHB1dCBzcGFjZSAqLwoKICAgIHRvcDogZG8gewogICAgICBpZiAoYml0cyA8IDE1KSB7CiAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0czsKICAgICAgICBiaXRzICs9IDg7CiAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0czsKICAgICAgICBiaXRzICs9IDg7CiAgICAgIH0KICAgICAgaGVyZSA9IGxjb2RlW2hvbGQgJiBsbWFza107CiAgICAgIGRvbGVuOiBmb3IgKDs7KSB7CiAgICAgICAgLy8gR290byBlbXVsYXRpb24KICAgICAgICBvcCA9IGhlcmUgPj4+IDI0IC8qaGVyZS5iaXRzKi87CiAgICAgICAgaG9sZCA+Pj49IG9wOwogICAgICAgIGJpdHMgLT0gb3A7CiAgICAgICAgb3AgPSBoZXJlID4+PiAxNiAmIDB4ZmYgLypoZXJlLm9wKi87CiAgICAgICAgaWYgKG9wID09PSAwKSB7CiAgICAgICAgICAvKiBsaXRlcmFsICovCiAgICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgaGVyZS52YWwgPj0gMHgyMCAmJiBoZXJlLnZhbCA8IDB4N2YgPwogICAgICAgICAgLy8gICAgICAgICJpbmZsYXRlOiAgICAgICAgIGxpdGVyYWwgJyVjJ1xuIiA6CiAgICAgICAgICAvLyAgICAgICAgImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAweCUwMnhcbiIsIGhlcmUudmFsKSk7CiAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGhlcmUgJiAweGZmZmYgLypoZXJlLnZhbCovOwogICAgICAgIH0gZWxzZSBpZiAob3AgJiAxNikgewogICAgICAgICAgLyogbGVuZ3RoIGJhc2UgKi8KICAgICAgICAgIGxlbiA9IGhlcmUgJiAweGZmZmYgLypoZXJlLnZhbCovOwogICAgICAgICAgb3AgJj0gMTU7IC8qIG51bWJlciBvZiBleHRyYSBiaXRzICovCiAgICAgICAgICBpZiAob3ApIHsKICAgICAgICAgICAgaWYgKGJpdHMgPCBvcCkgewogICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7CiAgICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxlbiArPSBob2xkICYgKDEgPDwgb3ApIC0gMTsKICAgICAgICAgICAgaG9sZCA+Pj49IG9wOwogICAgICAgICAgICBiaXRzIC09IG9wOwogICAgICAgICAgfQogICAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsICJpbmZsYXRlOiAgICAgICAgIGxlbmd0aCAldVxuIiwgbGVuKSk7CiAgICAgICAgICBpZiAoYml0cyA8IDE1KSB7CiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7CiAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0czsKICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgfQogICAgICAgICAgaGVyZSA9IGRjb2RlW2hvbGQgJiBkbWFza107CiAgICAgICAgICBkb2Rpc3Q6IGZvciAoOzspIHsKICAgICAgICAgICAgLy8gZ290byBlbXVsYXRpb24KICAgICAgICAgICAgb3AgPSBoZXJlID4+PiAyNCAvKmhlcmUuYml0cyovOwogICAgICAgICAgICBob2xkID4+Pj0gb3A7CiAgICAgICAgICAgIGJpdHMgLT0gb3A7CiAgICAgICAgICAgIG9wID0gaGVyZSA+Pj4gMTYgJiAweGZmIC8qaGVyZS5vcCovOwogICAgICAgICAgICBpZiAob3AgJiAxNikgewogICAgICAgICAgICAgIC8qIGRpc3RhbmNlIGJhc2UgKi8KICAgICAgICAgICAgICBkaXN0ID0gaGVyZSAmIDB4ZmZmZiAvKmhlcmUudmFsKi87CiAgICAgICAgICAgICAgb3AgJj0gMTU7IC8qIG51bWJlciBvZiBleHRyYSBiaXRzICovCiAgICAgICAgICAgICAgaWYgKGJpdHMgPCBvcCkgewogICAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0czsKICAgICAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgICAgICAgIGlmIChiaXRzIDwgb3ApIHsKICAgICAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0czsKICAgICAgICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkaXN0ICs9IGhvbGQgJiAoMSA8PCBvcCkgLSAxOwogICAgICAgICAgICAgIC8vI2lmZGVmIElORkxBVEVfU1RSSUNUCiAgICAgICAgICAgICAgaWYgKGRpc3QgPiBkbWF4KSB7CiAgICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7CiAgICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEJDE7CiAgICAgICAgICAgICAgICBicmVhayB0b3A7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8vI2VuZGlmCiAgICAgICAgICAgICAgaG9sZCA+Pj49IG9wOwogICAgICAgICAgICAgIGJpdHMgLT0gb3A7CiAgICAgICAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsICJpbmZsYXRlOiAgICAgICAgIGRpc3RhbmNlICV1XG4iLCBkaXN0KSk7CiAgICAgICAgICAgICAgb3AgPSBfb3V0IC0gYmVnOyAvKiBtYXggZGlzdGFuY2UgaW4gb3V0cHV0ICovCiAgICAgICAgICAgICAgaWYgKGRpc3QgPiBvcCkgewogICAgICAgICAgICAgICAgLyogc2VlIGlmIGNvcHkgZnJvbSB3aW5kb3cgKi8KICAgICAgICAgICAgICAgIG9wID0gZGlzdCAtIG9wOyAvKiBkaXN0YW5jZSBiYWNrIGluIHdpbmRvdyAqLwogICAgICAgICAgICAgICAgaWYgKG9wID4gd2hhdmUpIHsKICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlLnNhbmUpIHsKICAgICAgICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRCQxOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIHRvcDsKICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgLy8gKCEpIFRoaXMgYmxvY2sgaXMgZGlzYWJsZWQgaW4gemxpYiBkZWZhdWx0cywKICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eQogICAgICAgICAgICAgICAgICAvLyNpZmRlZiBJTkZMQVRFX0FMTE9XX0lOVkFMSURfRElTVEFOQ0VfVE9PRkFSX0FSUlIKICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgaWYgKGxlbiA8PSBvcCAtIHdoYXZlKSB7CiAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSAwOwogICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tbGVuKTsKICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICBjb250aW51ZSB0b3A7CiAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgbGVuIC09IG9wIC0gd2hhdmU7CiAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IDA7CiAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3AgPiB3aGF2ZSk7CiAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIGlmIChvcCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsKICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdOwogICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tbGVuKTsKICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICBjb250aW51ZSB0b3A7CiAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8jZW5kaWYKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZyb20gPSAwOyAvLyB3aW5kb3cgaW5kZXgKICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gc193aW5kb3c7CiAgICAgICAgICAgICAgICBpZiAod25leHQgPT09IDApIHsKICAgICAgICAgICAgICAgICAgLyogdmVyeSBjb21tb24gY2FzZSAqLwogICAgICAgICAgICAgICAgICBmcm9tICs9IHdzaXplIC0gb3A7CiAgICAgICAgICAgICAgICAgIGlmIChvcCA8IGxlbikgewogICAgICAgICAgICAgICAgICAgIC8qIHNvbWUgZnJvbSB3aW5kb3cgKi8KICAgICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7CiAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdOwogICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApOwogICAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsgLyogcmVzdCBmcm9tIG91dHB1dCAqLwogICAgICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHduZXh0IDwgb3ApIHsKICAgICAgICAgICAgICAgICAgLyogd3JhcCBhcm91bmQgd2luZG93ICovCiAgICAgICAgICAgICAgICAgIGZyb20gKz0gd3NpemUgKyB3bmV4dCAtIG9wOwogICAgICAgICAgICAgICAgICBvcCAtPSB3bmV4dDsKICAgICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7CiAgICAgICAgICAgICAgICAgICAgLyogc29tZSBmcm9tIGVuZCBvZiB3aW5kb3cgKi8KICAgICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7CiAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdOwogICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApOwogICAgICAgICAgICAgICAgICAgIGZyb20gPSAwOwogICAgICAgICAgICAgICAgICAgIGlmICh3bmV4dCA8IGxlbikgewogICAgICAgICAgICAgICAgICAgICAgLyogc29tZSBmcm9tIHN0YXJ0IG9mIHdpbmRvdyAqLwogICAgICAgICAgICAgICAgICAgICAgb3AgPSB3bmV4dDsKICAgICAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDsKICAgICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdOwogICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7CiAgICAgICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7IC8qIHJlc3QgZnJvbSBvdXRwdXQgKi8KICAgICAgICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgLyogY29udGlndW91cyBpbiB3aW5kb3cgKi8KICAgICAgICAgICAgICAgICAgZnJvbSArPSB3bmV4dCAtIG9wOwogICAgICAgICAgICAgICAgICBpZiAob3AgPCBsZW4pIHsKICAgICAgICAgICAgICAgICAgICAvKiBzb21lIGZyb20gd2luZG93ICovCiAgICAgICAgICAgICAgICAgICAgbGVuIC09IG9wOwogICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gc193aW5kb3dbZnJvbSsrXTsKICAgICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wKTsKICAgICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7IC8qIHJlc3QgZnJvbSBvdXRwdXQgKi8KICAgICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgd2hpbGUgKGxlbiA+IDIpIHsKICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdOwogICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107CiAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTsKICAgICAgICAgICAgICAgICAgbGVuIC09IDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAobGVuKSB7CiAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTsKICAgICAgICAgICAgICAgICAgaWYgKGxlbiA+IDEpIHsKICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0OyAvKiBjb3B5IGRpcmVjdCBmcm9tIG91dHB1dCAqLwogICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAvKiBtaW5pbXVtIGxlbmd0aCBpcyB0aHJlZSAqLwogICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdOwogICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdOwogICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdOwogICAgICAgICAgICAgICAgICBsZW4gLT0gMzsKICAgICAgICAgICAgICAgIH0gd2hpbGUgKGxlbiA+IDIpOwogICAgICAgICAgICAgICAgaWYgKGxlbikgewogICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdOwogICAgICAgICAgICAgICAgICBpZiAobGVuID4gMSkgewogICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoKG9wICYgNjQpID09PSAwKSB7CiAgICAgICAgICAgICAgLyogMm5kIGxldmVsIGRpc3RhbmNlIGNvZGUgKi8KICAgICAgICAgICAgICBoZXJlID0gZGNvZGVbKGhlcmUgJiAweGZmZmYgLypoZXJlLnZhbCovKSArIChob2xkICYgKDEgPDwgb3ApIC0gMSldOwogICAgICAgICAgICAgIGNvbnRpbnVlIGRvZGlzdDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIGNvZGUnOwogICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQkMTsKICAgICAgICAgICAgICBicmVhayB0b3A7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7IC8vIG5lZWQgdG8gZW11bGF0ZSBnb3RvIHZpYSAiY29udGludWUiCiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICgob3AgJiA2NCkgPT09IDApIHsKICAgICAgICAgIC8qIDJuZCBsZXZlbCBsZW5ndGggY29kZSAqLwogICAgICAgICAgaGVyZSA9IGxjb2RlWyhoZXJlICYgMHhmZmZmIC8qaGVyZS52YWwqLykgKyAoaG9sZCAmICgxIDw8IG9wKSAtIDEpXTsKICAgICAgICAgIGNvbnRpbnVlIGRvbGVuOwogICAgICAgIH0gZWxzZSBpZiAob3AgJiAzMikgewogICAgICAgICAgLyogZW5kLW9mLWJsb2NrICovCiAgICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgImluZmxhdGU6ICAgICAgICAgZW5kIG9mIGJsb2NrXG4iKSk7CiAgICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRSQxOwogICAgICAgICAgYnJlYWsgdG9wOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGxpdGVyYWwvbGVuZ3RoIGNvZGUnOwogICAgICAgICAgc3RhdGUubW9kZSA9IEJBRCQxOwogICAgICAgICAgYnJlYWsgdG9wOwogICAgICAgIH0KICAgICAgICBicmVhazsgLy8gbmVlZCB0byBlbXVsYXRlIGdvdG8gdmlhICJjb250aW51ZSIKICAgICAgfQogICAgfSB3aGlsZSAoX2luIDwgbGFzdCAmJiBfb3V0IDwgZW5kKTsKCiAgICAvKiByZXR1cm4gdW51c2VkIGJ5dGVzIChvbiBlbnRyeSwgYml0cyA8IDgsIHNvIGluIHdvbid0IGdvIHRvbyBmYXIgYmFjaykgKi8KICAgIGxlbiA9IGJpdHMgPj4gMzsKICAgIF9pbiAtPSBsZW47CiAgICBiaXRzIC09IGxlbiA8PCAzOwogICAgaG9sZCAmPSAoMSA8PCBiaXRzKSAtIDE7CgogICAgLyogdXBkYXRlIHN0YXRlIGFuZCByZXR1cm4gKi8KICAgIHN0cm0ubmV4dF9pbiA9IF9pbjsKICAgIHN0cm0ubmV4dF9vdXQgPSBfb3V0OwogICAgc3RybS5hdmFpbF9pbiA9IF9pbiA8IGxhc3QgPyA1ICsgKGxhc3QgLSBfaW4pIDogNSAtIChfaW4gLSBsYXN0KTsKICAgIHN0cm0uYXZhaWxfb3V0ID0gX291dCA8IGVuZCA/IDI1NyArIChlbmQgLSBfb3V0KSA6IDI1NyAtIChfb3V0IC0gZW5kKTsKICAgIHN0YXRlLmhvbGQgPSBob2xkOwogICAgc3RhdGUuYml0cyA9IGJpdHM7CiAgICByZXR1cm47CiAgfTsKCiAgLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyCiAgLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW4KICAvLwogIC8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkCiAgLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiAgLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KICAvLwogIC8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAogIC8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQKICAvLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAgLy8KICAvLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdAogIC8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKICAvLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogIC8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC4KICAvLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogIC8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgogIC8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgogIHZhciBNQVhCSVRTID0gMTU7CiAgdmFyIEVOT1VHSF9MRU5TJDEgPSA4NTI7CiAgdmFyIEVOT1VHSF9ESVNUUyQxID0gNTkyOwogIC8vY29uc3QgRU5PVUdIID0gKEVOT1VHSF9MRU5TK0VOT1VHSF9ESVNUUyk7CgogIHZhciBDT0RFUyQxID0gMDsKICB2YXIgTEVOUyQxID0gMTsKICB2YXIgRElTVFMkMSA9IDI7CiAgdmFyIGxiYXNlID0gbmV3IFVpbnQxNkFycmF5KFsvKiBMZW5ndGggY29kZXMgMjU3Li4yODUgYmFzZSAqLwogIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTMsIDE1LCAxNywgMTksIDIzLCAyNywgMzEsIDM1LCA0MywgNTEsIDU5LCA2NywgODMsIDk5LCAxMTUsIDEzMSwgMTYzLCAxOTUsIDIyNywgMjU4LCAwLCAwXSk7CiAgdmFyIGxleHQgPSBuZXcgVWludDhBcnJheShbLyogTGVuZ3RoIGNvZGVzIDI1Ny4uMjg1IGV4dHJhICovCiAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNywgMTcsIDE3LCAxNywgMTgsIDE4LCAxOCwgMTgsIDE5LCAxOSwgMTksIDE5LCAyMCwgMjAsIDIwLCAyMCwgMjEsIDIxLCAyMSwgMjEsIDE2LCA3MiwgNzhdKTsKICB2YXIgZGJhc2UgPSBuZXcgVWludDE2QXJyYXkoWy8qIERpc3RhbmNlIGNvZGVzIDAuLjI5IGJhc2UgKi8KICAxLCAyLCAzLCA0LCA1LCA3LCA5LCAxMywgMTcsIDI1LCAzMywgNDksIDY1LCA5NywgMTI5LCAxOTMsIDI1NywgMzg1LCA1MTMsIDc2OSwgMTAyNSwgMTUzNywgMjA0OSwgMzA3MywgNDA5NywgNjE0NSwgODE5MywgMTIyODksIDE2Mzg1LCAyNDU3NywgMCwgMF0pOwogIHZhciBkZXh0ID0gbmV3IFVpbnQ4QXJyYXkoWy8qIERpc3RhbmNlIGNvZGVzIDAuLjI5IGV4dHJhICovCiAgMTYsIDE2LCAxNiwgMTYsIDE3LCAxNywgMTgsIDE4LCAxOSwgMTksIDIwLCAyMCwgMjEsIDIxLCAyMiwgMjIsIDIzLCAyMywgMjQsIDI0LCAyNSwgMjUsIDI2LCAyNiwgMjcsIDI3LCAyOCwgMjgsIDI5LCAyOSwgNjQsIDY0XSk7CiAgdmFyIGluZmxhdGVfdGFibGUkMSA9IGZ1bmN0aW9uIGluZmxhdGVfdGFibGUodHlwZSwgbGVucywgbGVuc19pbmRleCwgY29kZXMsIHRhYmxlLCB0YWJsZV9pbmRleCwgd29yaywgb3B0cykgewogICAgdmFyIGJpdHMgPSBvcHRzLmJpdHM7CiAgICAvL2hlcmUgPSBvcHRzLmhlcmU7IC8qIHRhYmxlIGVudHJ5IGZvciBkdXBsaWNhdGlvbiAqLwoKICAgIHZhciBsZW4gPSAwOyAvKiBhIGNvZGUncyBsZW5ndGggaW4gYml0cyAqLwogICAgdmFyIHN5bSA9IDA7IC8qIGluZGV4IG9mIGNvZGUgc3ltYm9scyAqLwogICAgdmFyIG1pbiA9IDAsCiAgICAgIG1heCA9IDA7IC8qIG1pbmltdW0gYW5kIG1heGltdW0gY29kZSBsZW5ndGhzICovCiAgICB2YXIgcm9vdCA9IDA7IC8qIG51bWJlciBvZiBpbmRleCBiaXRzIGZvciByb290IHRhYmxlICovCiAgICB2YXIgY3VyciA9IDA7IC8qIG51bWJlciBvZiBpbmRleCBiaXRzIGZvciBjdXJyZW50IHRhYmxlICovCiAgICB2YXIgZHJvcCA9IDA7IC8qIGNvZGUgYml0cyB0byBkcm9wIGZvciBzdWItdGFibGUgKi8KICAgIHZhciBsZWZ0ID0gMDsgLyogbnVtYmVyIG9mIHByZWZpeCBjb2RlcyBhdmFpbGFibGUgKi8KICAgIHZhciB1c2VkID0gMDsgLyogY29kZSBlbnRyaWVzIGluIHRhYmxlIHVzZWQgKi8KICAgIHZhciBodWZmID0gMDsgLyogSHVmZm1hbiBjb2RlICovCiAgICB2YXIgaW5jcjsgLyogZm9yIGluY3JlbWVudGluZyBjb2RlLCBpbmRleCAqLwogICAgdmFyIGZpbGw7IC8qIGluZGV4IGZvciByZXBsaWNhdGluZyBlbnRyaWVzICovCiAgICB2YXIgbG93OyAvKiBsb3cgYml0cyBmb3IgY3VycmVudCByb290IGVudHJ5ICovCiAgICB2YXIgbWFzazsgLyogbWFzayBmb3IgbG93IHJvb3QgYml0cyAqLwogICAgdmFyIG5leHQ7IC8qIG5leHQgYXZhaWxhYmxlIHNwYWNlIGluIHRhYmxlICovCiAgICB2YXIgYmFzZSA9IG51bGw7IC8qIGJhc2UgdmFsdWUgdGFibGUgdG8gdXNlICovCiAgICB2YXIgYmFzZV9pbmRleCA9IDA7CiAgICAvLyAgbGV0IHNob2V4dHJhOyAgICAvKiBleHRyYSBiaXRzIHRhYmxlIHRvIHVzZSAqLwogICAgdmFyIGVuZDsgLyogdXNlIGJhc2UgYW5kIGV4dHJhIGZvciBzeW1ib2wgPiBlbmQgKi8KICAgIHZhciBjb3VudCA9IG5ldyBVaW50MTZBcnJheShNQVhCSVRTICsgMSk7IC8vW01BWEJJVFMrMV07ICAgIC8qIG51bWJlciBvZiBjb2RlcyBvZiBlYWNoIGxlbmd0aCAqLwogICAgdmFyIG9mZnMgPSBuZXcgVWludDE2QXJyYXkoTUFYQklUUyArIDEpOyAvL1tNQVhCSVRTKzFdOyAgICAgLyogb2Zmc2V0cyBpbiB0YWJsZSBmb3IgZWFjaCBsZW5ndGggKi8KICAgIHZhciBleHRyYSA9IG51bGw7CiAgICB2YXIgZXh0cmFfaW5kZXggPSAwOwogICAgdmFyIGhlcmVfYml0cywgaGVyZV9vcCwgaGVyZV92YWw7CgogICAgLyoKICAgICBQcm9jZXNzIGEgc2V0IG9mIGNvZGUgbGVuZ3RocyB0byBjcmVhdGUgYSBjYW5vbmljYWwgSHVmZm1hbiBjb2RlLiAgVGhlCiAgICAgY29kZSBsZW5ndGhzIGFyZSBsZW5zWzAuLmNvZGVzLTFdLiAgRWFjaCBsZW5ndGggY29ycmVzcG9uZHMgdG8gdGhlCiAgICAgc3ltYm9scyAwLi5jb2Rlcy0xLiAgVGhlIEh1ZmZtYW4gY29kZSBpcyBnZW5lcmF0ZWQgYnkgZmlyc3Qgc29ydGluZyB0aGUKICAgICBzeW1ib2xzIGJ5IGxlbmd0aCBmcm9tIHNob3J0IHRvIGxvbmcsIGFuZCByZXRhaW5pbmcgdGhlIHN5bWJvbCBvcmRlcgogICAgIGZvciBjb2RlcyB3aXRoIGVxdWFsIGxlbmd0aHMuICBUaGVuIHRoZSBjb2RlIHN0YXJ0cyB3aXRoIGFsbCB6ZXJvIGJpdHMKICAgICBmb3IgdGhlIGZpcnN0IGNvZGUgb2YgdGhlIHNob3J0ZXN0IGxlbmd0aCwgYW5kIHRoZSBjb2RlcyBhcmUgaW50ZWdlcgogICAgIGluY3JlbWVudHMgZm9yIHRoZSBzYW1lIGxlbmd0aCwgYW5kIHplcm9zIGFyZSBhcHBlbmRlZCBhcyB0aGUgbGVuZ3RoCiAgICAgaW5jcmVhc2VzLiAgRm9yIHRoZSBkZWZsYXRlIGZvcm1hdCwgdGhlc2UgYml0cyBhcmUgc3RvcmVkIGJhY2t3YXJkcwogICAgIGZyb20gdGhlaXIgbW9yZSBuYXR1cmFsIGludGVnZXIgaW5jcmVtZW50IG9yZGVyaW5nLCBhbmQgc28gd2hlbiB0aGUKICAgICBkZWNvZGluZyB0YWJsZXMgYXJlIGJ1aWx0IGluIHRoZSBsYXJnZSBsb29wIGJlbG93LCB0aGUgaW50ZWdlciBjb2RlcwogICAgIGFyZSBpbmNyZW1lbnRlZCBiYWNrd2FyZHMuCiAgICAgIFRoaXMgcm91dGluZSBhc3N1bWVzLCBidXQgZG9lcyBub3QgY2hlY2ssIHRoYXQgYWxsIG9mIHRoZSBlbnRyaWVzIGluCiAgICAgbGVuc1tdIGFyZSBpbiB0aGUgcmFuZ2UgMC4uTUFYQklUUy4gIFRoZSBjYWxsZXIgbXVzdCBhc3N1cmUgdGhpcy4KICAgICAxLi5NQVhCSVRTIGlzIGludGVycHJldGVkIGFzIHRoYXQgY29kZSBsZW5ndGguICB6ZXJvIG1lYW5zIHRoYXQgdGhhdAogICAgIHN5bWJvbCBkb2VzIG5vdCBvY2N1ciBpbiB0aGlzIGNvZGUuCiAgICAgIFRoZSBjb2RlcyBhcmUgc29ydGVkIGJ5IGNvbXB1dGluZyBhIGNvdW50IG9mIGNvZGVzIGZvciBlYWNoIGxlbmd0aCwKICAgICBjcmVhdGluZyBmcm9tIHRoYXQgYSB0YWJsZSBvZiBzdGFydGluZyBpbmRpY2VzIGZvciBlYWNoIGxlbmd0aCBpbiB0aGUKICAgICBzb3J0ZWQgdGFibGUsIGFuZCB0aGVuIGVudGVyaW5nIHRoZSBzeW1ib2xzIGluIG9yZGVyIGluIHRoZSBzb3J0ZWQKICAgICB0YWJsZS4gIFRoZSBzb3J0ZWQgdGFibGUgaXMgd29ya1tdLCB3aXRoIHRoYXQgc3BhY2UgYmVpbmcgcHJvdmlkZWQgYnkKICAgICB0aGUgY2FsbGVyLgogICAgICBUaGUgbGVuZ3RoIGNvdW50cyBhcmUgdXNlZCBmb3Igb3RoZXIgcHVycG9zZXMgYXMgd2VsbCwgaS5lLiBmaW5kaW5nCiAgICAgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gbGVuZ3RoIGNvZGVzLCBkZXRlcm1pbmluZyBpZiB0aGVyZSBhcmUgYW55CiAgICAgY29kZXMgYXQgYWxsLCBjaGVja2luZyBmb3IgYSB2YWxpZCBzZXQgb2YgbGVuZ3RocywgYW5kIGxvb2tpbmcgYWhlYWQKICAgICBhdCBsZW5ndGggY291bnRzIHRvIGRldGVybWluZSBzdWItdGFibGUgc2l6ZXMgd2hlbiBidWlsZGluZyB0aGUKICAgICBkZWNvZGluZyB0YWJsZXMuCiAgICAgKi8KCiAgICAvKiBhY2N1bXVsYXRlIGxlbmd0aHMgZm9yIGNvZGVzIChhc3N1bWVzIGxlbnNbXSBhbGwgaW4gMC4uTUFYQklUUykgKi8KICAgIGZvciAobGVuID0gMDsgbGVuIDw9IE1BWEJJVFM7IGxlbisrKSB7CiAgICAgIGNvdW50W2xlbl0gPSAwOwogICAgfQogICAgZm9yIChzeW0gPSAwOyBzeW0gPCBjb2Rlczsgc3ltKyspIHsKICAgICAgY291bnRbbGVuc1tsZW5zX2luZGV4ICsgc3ltXV0rKzsKICAgIH0KCiAgICAvKiBib3VuZCBjb2RlIGxlbmd0aHMsIGZvcmNlIHJvb3QgdG8gYmUgd2l0aGluIGNvZGUgbGVuZ3RocyAqLwogICAgcm9vdCA9IGJpdHM7CiAgICBmb3IgKG1heCA9IE1BWEJJVFM7IG1heCA+PSAxOyBtYXgtLSkgewogICAgICBpZiAoY291bnRbbWF4XSAhPT0gMCkgewogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgICBpZiAocm9vdCA+IG1heCkgewogICAgICByb290ID0gbWF4OwogICAgfQogICAgaWYgKG1heCA9PT0gMCkgewogICAgICAvKiBubyBzeW1ib2xzIHRvIGNvZGUgYXQgYWxsICovCiAgICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDsgIC8vaGVyZS5vcCA9ICh2YXIgY2hhcik2NDsgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqLwogICAgICAvL3RhYmxlLmJpdHNbb3B0cy50YWJsZV9pbmRleF0gPSAxOyAgIC8vaGVyZS5iaXRzID0gKHZhciBjaGFyKTE7CiAgICAgIC8vdGFibGUudmFsW29wdHMudGFibGVfaW5kZXgrK10gPSAwOyAgIC8vaGVyZS52YWwgPSAodmFyIHNob3J0KTA7CiAgICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gMSA8PCAyNCB8IDY0IDw8IDE2IHwgMDsKCiAgICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDsKICAgICAgLy90YWJsZS5iaXRzW29wdHMudGFibGVfaW5kZXhdID0gMTsKICAgICAgLy90YWJsZS52YWxbb3B0cy50YWJsZV9pbmRleCsrXSA9IDA7CiAgICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gMSA8PCAyNCB8IDY0IDw8IDE2IHwgMDsKICAgICAgb3B0cy5iaXRzID0gMTsKICAgICAgcmV0dXJuIDA7IC8qIG5vIHN5bWJvbHMsIGJ1dCB3YWl0IGZvciBkZWNvZGluZyB0byByZXBvcnQgZXJyb3IgKi8KICAgIH0KICAgIGZvciAobWluID0gMTsgbWluIDwgbWF4OyBtaW4rKykgewogICAgICBpZiAoY291bnRbbWluXSAhPT0gMCkgewogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgICBpZiAocm9vdCA8IG1pbikgewogICAgICByb290ID0gbWluOwogICAgfQoKICAgIC8qIGNoZWNrIGZvciBhbiBvdmVyLXN1YnNjcmliZWQgb3IgaW5jb21wbGV0ZSBzZXQgb2YgbGVuZ3RocyAqLwogICAgbGVmdCA9IDE7CiAgICBmb3IgKGxlbiA9IDE7IGxlbiA8PSBNQVhCSVRTOyBsZW4rKykgewogICAgICBsZWZ0IDw8PSAxOwogICAgICBsZWZ0IC09IGNvdW50W2xlbl07CiAgICAgIGlmIChsZWZ0IDwgMCkgewogICAgICAgIHJldHVybiAtMTsKICAgICAgfSAvKiBvdmVyLXN1YnNjcmliZWQgKi8KICAgIH0KICAgIGlmIChsZWZ0ID4gMCAmJiAodHlwZSA9PT0gQ09ERVMkMSB8fCBtYXggIT09IDEpKSB7CiAgICAgIHJldHVybiAtMTsgLyogaW5jb21wbGV0ZSBzZXQgKi8KICAgIH0KCiAgICAvKiBnZW5lcmF0ZSBvZmZzZXRzIGludG8gc3ltYm9sIHRhYmxlIGZvciBlYWNoIGxlbmd0aCBmb3Igc29ydGluZyAqLwogICAgb2Zmc1sxXSA9IDA7CiAgICBmb3IgKGxlbiA9IDE7IGxlbiA8IE1BWEJJVFM7IGxlbisrKSB7CiAgICAgIG9mZnNbbGVuICsgMV0gPSBvZmZzW2xlbl0gKyBjb3VudFtsZW5dOwogICAgfQoKICAgIC8qIHNvcnQgc3ltYm9scyBieSBsZW5ndGgsIGJ5IHN5bWJvbCBvcmRlciB3aXRoaW4gZWFjaCBsZW5ndGggKi8KICAgIGZvciAoc3ltID0gMDsgc3ltIDwgY29kZXM7IHN5bSsrKSB7CiAgICAgIGlmIChsZW5zW2xlbnNfaW5kZXggKyBzeW1dICE9PSAwKSB7CiAgICAgICAgd29ya1tvZmZzW2xlbnNbbGVuc19pbmRleCArIHN5bV1dKytdID0gc3ltOwogICAgICB9CiAgICB9CgogICAgLyoKICAgICBDcmVhdGUgYW5kIGZpbGwgaW4gZGVjb2RpbmcgdGFibGVzLiAgSW4gdGhpcyBsb29wLCB0aGUgdGFibGUgYmVpbmcKICAgICBmaWxsZWQgaXMgYXQgbmV4dCBhbmQgaGFzIGN1cnIgaW5kZXggYml0cy4gIFRoZSBjb2RlIGJlaW5nIHVzZWQgaXMgaHVmZgogICAgIHdpdGggbGVuZ3RoIGxlbi4gIFRoYXQgY29kZSBpcyBjb252ZXJ0ZWQgdG8gYW4gaW5kZXggYnkgZHJvcHBpbmcgZHJvcAogICAgIGJpdHMgb2ZmIG9mIHRoZSBib3R0b20uICBGb3IgY29kZXMgd2hlcmUgbGVuIGlzIGxlc3MgdGhhbiBkcm9wICsgY3VyciwKICAgICB0aG9zZSB0b3AgZHJvcCArIGN1cnIgLSBsZW4gYml0cyBhcmUgaW5jcmVtZW50ZWQgdGhyb3VnaCBhbGwgdmFsdWVzIHRvCiAgICAgZmlsbCB0aGUgdGFibGUgd2l0aCByZXBsaWNhdGVkIGVudHJpZXMuCiAgICAgIHJvb3QgaXMgdGhlIG51bWJlciBvZiBpbmRleCBiaXRzIGZvciB0aGUgcm9vdCB0YWJsZS4gIFdoZW4gbGVuIGV4Y2VlZHMKICAgICByb290LCBzdWItdGFibGVzIGFyZSBjcmVhdGVkIHBvaW50ZWQgdG8gYnkgdGhlIHJvb3QgZW50cnkgd2l0aCBhbiBpbmRleAogICAgIG9mIHRoZSBsb3cgcm9vdCBiaXRzIG9mIGh1ZmYuICBUaGlzIGlzIHNhdmVkIGluIGxvdyB0byBjaGVjayBmb3Igd2hlbiBhCiAgICAgbmV3IHN1Yi10YWJsZSBzaG91bGQgYmUgc3RhcnRlZC4gIGRyb3AgaXMgemVybyB3aGVuIHRoZSByb290IHRhYmxlIGlzCiAgICAgYmVpbmcgZmlsbGVkLCBhbmQgZHJvcCBpcyByb290IHdoZW4gc3ViLXRhYmxlcyBhcmUgYmVpbmcgZmlsbGVkLgogICAgICBXaGVuIGEgbmV3IHN1Yi10YWJsZSBpcyBuZWVkZWQsIGl0IGlzIG5lY2Vzc2FyeSB0byBsb29rIGFoZWFkIGluIHRoZQogICAgIGNvZGUgbGVuZ3RocyB0byBkZXRlcm1pbmUgd2hhdCBzaXplIHN1Yi10YWJsZSBpcyBuZWVkZWQuICBUaGUgbGVuZ3RoCiAgICAgY291bnRzIGFyZSB1c2VkIGZvciB0aGlzLCBhbmQgc28gY291bnRbXSBpcyBkZWNyZW1lbnRlZCBhcyBjb2RlcyBhcmUKICAgICBlbnRlcmVkIGluIHRoZSB0YWJsZXMuCiAgICAgIHVzZWQga2VlcHMgdHJhY2sgb2YgaG93IG1hbnkgdGFibGUgZW50cmllcyBoYXZlIGJlZW4gYWxsb2NhdGVkIGZyb20gdGhlCiAgICAgcHJvdmlkZWQgKnRhYmxlIHNwYWNlLiAgSXQgaXMgY2hlY2tlZCBmb3IgTEVOUyBhbmQgRElTVCB0YWJsZXMgYWdhaW5zdAogICAgIHRoZSBjb25zdGFudHMgRU5PVUdIX0xFTlMgYW5kIEVOT1VHSF9ESVNUUyB0byBndWFyZCBhZ2FpbnN0IGNoYW5nZXMgaW4KICAgICB0aGUgaW5pdGlhbCByb290IHRhYmxlIHNpemUgY29uc3RhbnRzLiAgU2VlIHRoZSBjb21tZW50cyBpbiBpbmZ0cmVlcy5oCiAgICAgZm9yIG1vcmUgaW5mb3JtYXRpb24uCiAgICAgIHN5bSBpbmNyZW1lbnRzIHRocm91Z2ggYWxsIHN5bWJvbHMsIGFuZCB0aGUgbG9vcCB0ZXJtaW5hdGVzIHdoZW4KICAgICBhbGwgY29kZXMgb2YgbGVuZ3RoIG1heCwgaS5lLiBhbGwgY29kZXMsIGhhdmUgYmVlbiBwcm9jZXNzZWQuICBUaGlzCiAgICAgcm91dGluZSBwZXJtaXRzIGluY29tcGxldGUgY29kZXMsIHNvIGFub3RoZXIgbG9vcCBhZnRlciB0aGlzIG9uZSBmaWxscwogICAgIGluIHRoZSByZXN0IG9mIHRoZSBkZWNvZGluZyB0YWJsZXMgd2l0aCBpbnZhbGlkIGNvZGUgbWFya2Vycy4KICAgICAqLwoKICAgIC8qIHNldCB1cCBmb3IgY29kZSB0eXBlICovCiAgICAvLyBwb29yIG1hbiBvcHRpbWl6YXRpb24gLSB1c2UgaWYtZWxzZSBpbnN0ZWFkIG9mIHN3aXRjaCwKICAgIC8vIHRvIGF2b2lkIGRlb3B0cyBpbiBvbGQgdjgKICAgIGlmICh0eXBlID09PSBDT0RFUyQxKSB7CiAgICAgIGJhc2UgPSBleHRyYSA9IHdvcms7IC8qIGR1bW15IHZhbHVlLS1ub3QgdXNlZCAqLwogICAgICBlbmQgPSAxOTsKICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gTEVOUyQxKSB7CiAgICAgIGJhc2UgPSBsYmFzZTsKICAgICAgYmFzZV9pbmRleCAtPSAyNTc7CiAgICAgIGV4dHJhID0gbGV4dDsKICAgICAgZXh0cmFfaW5kZXggLT0gMjU3OwogICAgICBlbmQgPSAyNTY7CiAgICB9IGVsc2UgewogICAgICAvKiBESVNUUyAqLwogICAgICBiYXNlID0gZGJhc2U7CiAgICAgIGV4dHJhID0gZGV4dDsKICAgICAgZW5kID0gLTE7CiAgICB9CgogICAgLyogaW5pdGlhbGl6ZSBvcHRzIGZvciBsb29wICovCiAgICBodWZmID0gMDsgLyogc3RhcnRpbmcgY29kZSAqLwogICAgc3ltID0gMDsgLyogc3RhcnRpbmcgY29kZSBzeW1ib2wgKi8KICAgIGxlbiA9IG1pbjsgLyogc3RhcnRpbmcgY29kZSBsZW5ndGggKi8KICAgIG5leHQgPSB0YWJsZV9pbmRleDsgLyogY3VycmVudCB0YWJsZSB0byBmaWxsIGluICovCiAgICBjdXJyID0gcm9vdDsgLyogY3VycmVudCB0YWJsZSBpbmRleCBiaXRzICovCiAgICBkcm9wID0gMDsgLyogY3VycmVudCBiaXRzIHRvIGRyb3AgZnJvbSBjb2RlIGZvciBpbmRleCAqLwogICAgbG93ID0gLTE7IC8qIHRyaWdnZXIgbmV3IHN1Yi10YWJsZSB3aGVuIGxlbiA+IHJvb3QgKi8KICAgIHVzZWQgPSAxIDw8IHJvb3Q7IC8qIHVzZSByb290IHRhYmxlIGVudHJpZXMgKi8KICAgIG1hc2sgPSB1c2VkIC0gMTsgLyogbWFzayBmb3IgY29tcGFyaW5nIGxvdyAqLwoKICAgIC8qIGNoZWNrIGF2YWlsYWJsZSB0YWJsZSBzcGFjZSAqLwogICAgaWYgKHR5cGUgPT09IExFTlMkMSAmJiB1c2VkID4gRU5PVUdIX0xFTlMkMSB8fCB0eXBlID09PSBESVNUUyQxICYmIHVzZWQgPiBFTk9VR0hfRElTVFMkMSkgewogICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAvKiBwcm9jZXNzIGFsbCBjb2RlcyBhbmQgbWFrZSB0YWJsZSBlbnRyaWVzICovCiAgICBmb3IgKDs7KSB7CiAgICAgIC8qIGNyZWF0ZSB0YWJsZSBlbnRyeSAqLwogICAgICBoZXJlX2JpdHMgPSBsZW4gLSBkcm9wOwogICAgICBpZiAod29ya1tzeW1dIDwgZW5kKSB7CiAgICAgICAgaGVyZV9vcCA9IDA7CiAgICAgICAgaGVyZV92YWwgPSB3b3JrW3N5bV07CiAgICAgIH0gZWxzZSBpZiAod29ya1tzeW1dID4gZW5kKSB7CiAgICAgICAgaGVyZV9vcCA9IGV4dHJhW2V4dHJhX2luZGV4ICsgd29ya1tzeW1dXTsKICAgICAgICBoZXJlX3ZhbCA9IGJhc2VbYmFzZV9pbmRleCArIHdvcmtbc3ltXV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaGVyZV9vcCA9IDMyICsgNjQ7IC8qIGVuZCBvZiBibG9jayAqLwogICAgICAgIGhlcmVfdmFsID0gMDsKICAgICAgfQoKICAgICAgLyogcmVwbGljYXRlIGZvciB0aG9zZSBpbmRpY2VzIHdpdGggbG93IGxlbiBiaXRzIGVxdWFsIHRvIGh1ZmYgKi8KICAgICAgaW5jciA9IDEgPDwgbGVuIC0gZHJvcDsKICAgICAgZmlsbCA9IDEgPDwgY3VycjsKICAgICAgbWluID0gZmlsbDsgLyogc2F2ZSBvZmZzZXQgdG8gbmV4dCB0YWJsZSAqLwogICAgICBkbyB7CiAgICAgICAgZmlsbCAtPSBpbmNyOwogICAgICAgIHRhYmxlW25leHQgKyAoaHVmZiA+PiBkcm9wKSArIGZpbGxdID0gaGVyZV9iaXRzIDw8IDI0IHwgaGVyZV9vcCA8PCAxNiB8IGhlcmVfdmFsIHwgMDsKICAgICAgfSB3aGlsZSAoZmlsbCAhPT0gMCk7CgogICAgICAvKiBiYWNrd2FyZHMgaW5jcmVtZW50IHRoZSBsZW4tYml0IGNvZGUgaHVmZiAqLwogICAgICBpbmNyID0gMSA8PCBsZW4gLSAxOwogICAgICB3aGlsZSAoaHVmZiAmIGluY3IpIHsKICAgICAgICBpbmNyID4+PSAxOwogICAgICB9CiAgICAgIGlmIChpbmNyICE9PSAwKSB7CiAgICAgICAgaHVmZiAmPSBpbmNyIC0gMTsKICAgICAgICBodWZmICs9IGluY3I7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaHVmZiA9IDA7CiAgICAgIH0KCiAgICAgIC8qIGdvIHRvIG5leHQgc3ltYm9sLCB1cGRhdGUgY291bnQsIGxlbiAqLwogICAgICBzeW0rKzsKICAgICAgaWYgKC0tY291bnRbbGVuXSA9PT0gMCkgewogICAgICAgIGlmIChsZW4gPT09IG1heCkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxlbiA9IGxlbnNbbGVuc19pbmRleCArIHdvcmtbc3ltXV07CiAgICAgIH0KCiAgICAgIC8qIGNyZWF0ZSBuZXcgc3ViLXRhYmxlIGlmIG5lZWRlZCAqLwogICAgICBpZiAobGVuID4gcm9vdCAmJiAoaHVmZiAmIG1hc2spICE9PSBsb3cpIHsKICAgICAgICAvKiBpZiBmaXJzdCB0aW1lLCB0cmFuc2l0aW9uIHRvIHN1Yi10YWJsZXMgKi8KICAgICAgICBpZiAoZHJvcCA9PT0gMCkgewogICAgICAgICAgZHJvcCA9IHJvb3Q7CiAgICAgICAgfQoKICAgICAgICAvKiBpbmNyZW1lbnQgcGFzdCBsYXN0IHRhYmxlICovCiAgICAgICAgbmV4dCArPSBtaW47IC8qIGhlcmUgbWluIGlzIDEgPDwgY3VyciAqLwoKICAgICAgICAvKiBkZXRlcm1pbmUgbGVuZ3RoIG9mIG5leHQgdGFibGUgKi8KICAgICAgICBjdXJyID0gbGVuIC0gZHJvcDsKICAgICAgICBsZWZ0ID0gMSA8PCBjdXJyOwogICAgICAgIHdoaWxlIChjdXJyICsgZHJvcCA8IG1heCkgewogICAgICAgICAgbGVmdCAtPSBjb3VudFtjdXJyICsgZHJvcF07CiAgICAgICAgICBpZiAobGVmdCA8PSAwKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY3VycisrOwogICAgICAgICAgbGVmdCA8PD0gMTsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIGZvciBlbm91Z2ggc3BhY2UgKi8KICAgICAgICB1c2VkICs9IDEgPDwgY3VycjsKICAgICAgICBpZiAodHlwZSA9PT0gTEVOUyQxICYmIHVzZWQgPiBFTk9VR0hfTEVOUyQxIHx8IHR5cGUgPT09IERJU1RTJDEgJiYgdXNlZCA+IEVOT1VHSF9ESVNUUyQxKSB7CiAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIC8qIHBvaW50IGVudHJ5IGluIHJvb3QgdGFibGUgdG8gc3ViLXRhYmxlICovCiAgICAgICAgbG93ID0gaHVmZiAmIG1hc2s7CiAgICAgICAgLyp0YWJsZS5vcFtsb3ddID0gY3VycjsKICAgICAgICB0YWJsZS5iaXRzW2xvd10gPSByb290OwogICAgICAgIHRhYmxlLnZhbFtsb3ddID0gbmV4dCAtIG9wdHMudGFibGVfaW5kZXg7Ki8KICAgICAgICB0YWJsZVtsb3ddID0gcm9vdCA8PCAyNCB8IGN1cnIgPDwgMTYgfCBuZXh0IC0gdGFibGVfaW5kZXggfCAwOwogICAgICB9CiAgICB9CgogICAgLyogZmlsbCBpbiByZW1haW5pbmcgdGFibGUgZW50cnkgaWYgY29kZSBpcyBpbmNvbXBsZXRlIChndWFyYW50ZWVkIHRvIGhhdmUKICAgICBhdCBtb3N0IG9uZSByZW1haW5pbmcgZW50cnksIHNpbmNlIGlmIHRoZSBjb2RlIGlzIGluY29tcGxldGUsIHRoZQogICAgIG1heGltdW0gY29kZSBsZW5ndGggdGhhdCB3YXMgYWxsb3dlZCB0byBnZXQgdGhpcyBmYXIgaXMgb25lIGJpdCkgKi8KICAgIGlmIChodWZmICE9PSAwKSB7CiAgICAgIC8vdGFibGUub3BbbmV4dCArIGh1ZmZdID0gNjQ7ICAgICAgICAgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqLwogICAgICAvL3RhYmxlLmJpdHNbbmV4dCArIGh1ZmZdID0gbGVuIC0gZHJvcDsKICAgICAgLy90YWJsZS52YWxbbmV4dCArIGh1ZmZdID0gMDsKICAgICAgdGFibGVbbmV4dCArIGh1ZmZdID0gbGVuIC0gZHJvcCA8PCAyNCB8IDY0IDw8IDE2IHwgMDsKICAgIH0KCiAgICAvKiBzZXQgcmV0dXJuIHBhcmFtZXRlcnMgKi8KICAgIC8vb3B0cy50YWJsZV9pbmRleCArPSB1c2VkOwogICAgb3B0cy5iaXRzID0gcm9vdDsKICAgIHJldHVybiAwOwogIH07CiAgdmFyIGluZnRyZWVzID0gaW5mbGF0ZV90YWJsZSQxOwoKICAvLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXIKICAvLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpbgogIC8vCiAgLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICAvLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKICAvLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogIC8vCiAgLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiAgLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogIC8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKICAvLwogIC8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAgLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZQogIC8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiAgLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogIC8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiAgLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAgLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KCiAgdmFyIGFkbGVyMzIgPSBhZGxlcjMyXzE7CiAgdmFyIGNyYzMyID0gY3JjMzJfMTsKICB2YXIgaW5mbGF0ZV9mYXN0ID0gaW5mZmFzdDsKICB2YXIgaW5mbGF0ZV90YWJsZSA9IGluZnRyZWVzOwogIHZhciBDT0RFUyA9IDA7CiAgdmFyIExFTlMgPSAxOwogIHZhciBESVNUUyA9IDI7CgogIC8qIFB1YmxpYyBjb25zdGFudHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KCiAgdmFyIFpfRklOSVNIJDEgPSBjb25zdGFudHMkMS5aX0ZJTklTSCwKICAgIFpfQkxPQ0sgPSBjb25zdGFudHMkMS5aX0JMT0NLLAogICAgWl9UUkVFUyA9IGNvbnN0YW50cyQxLlpfVFJFRVMsCiAgICBaX09LJDEgPSBjb25zdGFudHMkMS5aX09LLAogICAgWl9TVFJFQU1fRU5EJDEgPSBjb25zdGFudHMkMS5aX1NUUkVBTV9FTkQsCiAgICBaX05FRURfRElDVCQxID0gY29uc3RhbnRzJDEuWl9ORUVEX0RJQ1QsCiAgICBaX1NUUkVBTV9FUlJPUiQxID0gY29uc3RhbnRzJDEuWl9TVFJFQU1fRVJST1IsCiAgICBaX0RBVEFfRVJST1IkMSA9IGNvbnN0YW50cyQxLlpfREFUQV9FUlJPUiwKICAgIFpfTUVNX0VSUk9SJDEgPSBjb25zdGFudHMkMS5aX01FTV9FUlJPUiwKICAgIFpfQlVGX0VSUk9SID0gY29uc3RhbnRzJDEuWl9CVUZfRVJST1IsCiAgICBaX0RFRkxBVEVEID0gY29uc3RhbnRzJDEuWl9ERUZMQVRFRDsKCiAgLyogU1RBVEVTID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKICB2YXIgSEVBRCA9IDE7IC8qIGk6IHdhaXRpbmcgZm9yIG1hZ2ljIGhlYWRlciAqLwogIHZhciBGTEFHUyA9IDI7IC8qIGk6IHdhaXRpbmcgZm9yIG1ldGhvZCBhbmQgZmxhZ3MgKGd6aXApICovCiAgdmFyIFRJTUUgPSAzOyAvKiBpOiB3YWl0aW5nIGZvciBtb2RpZmljYXRpb24gdGltZSAoZ3ppcCkgKi8KICB2YXIgT1MgPSA0OyAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBmbGFncyBhbmQgb3BlcmF0aW5nIHN5c3RlbSAoZ3ppcCkgKi8KICB2YXIgRVhMRU4gPSA1OyAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBsZW5ndGggKGd6aXApICovCiAgdmFyIEVYVFJBID0gNjsgLyogaTogd2FpdGluZyBmb3IgZXh0cmEgYnl0ZXMgKGd6aXApICovCiAgdmFyIE5BTUUgPSA3OyAvKiBpOiB3YWl0aW5nIGZvciBlbmQgb2YgZmlsZSBuYW1lIChnemlwKSAqLwogIHZhciBDT01NRU5UID0gODsgLyogaTogd2FpdGluZyBmb3IgZW5kIG9mIGNvbW1lbnQgKGd6aXApICovCiAgdmFyIEhDUkMgPSA5OyAvKiBpOiB3YWl0aW5nIGZvciBoZWFkZXIgY3JjIChnemlwKSAqLwogIHZhciBESUNUSUQgPSAxMDsgLyogaTogd2FpdGluZyBmb3IgZGljdGlvbmFyeSBjaGVjayB2YWx1ZSAqLwogIHZhciBESUNUID0gMTE7IC8qIHdhaXRpbmcgZm9yIGluZmxhdGVTZXREaWN0aW9uYXJ5KCkgY2FsbCAqLwogIHZhciBUWVBFID0gMTI7IC8qIGk6IHdhaXRpbmcgZm9yIHR5cGUgYml0cywgaW5jbHVkaW5nIGxhc3QtZmxhZyBiaXQgKi8KICB2YXIgVFlQRURPID0gMTM7IC8qIGk6IHNhbWUsIGJ1dCBza2lwIGNoZWNrIHRvIGV4aXQgaW5mbGF0ZSBvbiBuZXcgYmxvY2sgKi8KICB2YXIgU1RPUkVEID0gMTQ7IC8qIGk6IHdhaXRpbmcgZm9yIHN0b3JlZCBzaXplIChsZW5ndGggYW5kIGNvbXBsZW1lbnQpICovCiAgdmFyIENPUFlfID0gMTU7IC8qIGkvbzogc2FtZSBhcyBDT1BZIGJlbG93LCBidXQgb25seSBmaXJzdCB0aW1lIGluICovCiAgdmFyIENPUFkgPSAxNjsgLyogaS9vOiB3YWl0aW5nIGZvciBpbnB1dCBvciBvdXRwdXQgdG8gY29weSBzdG9yZWQgYmxvY2sgKi8KICB2YXIgVEFCTEUgPSAxNzsgLyogaTogd2FpdGluZyBmb3IgZHluYW1pYyBibG9jayB0YWJsZSBsZW5ndGhzICovCiAgdmFyIExFTkxFTlMgPSAxODsgLyogaTogd2FpdGluZyBmb3IgY29kZSBsZW5ndGggY29kZSBsZW5ndGhzICovCiAgdmFyIENPREVMRU5TID0gMTk7IC8qIGk6IHdhaXRpbmcgZm9yIGxlbmd0aC9saXQgYW5kIGRpc3RhbmNlIGNvZGUgbGVuZ3RocyAqLwogIHZhciBMRU5fID0gMjA7IC8qIGk6IHNhbWUgYXMgTEVOIGJlbG93LCBidXQgb25seSBmaXJzdCB0aW1lIGluICovCiAgdmFyIExFTiA9IDIxOyAvKiBpOiB3YWl0aW5nIGZvciBsZW5ndGgvbGl0L2VvYiBjb2RlICovCiAgdmFyIExFTkVYVCA9IDIyOyAvKiBpOiB3YWl0aW5nIGZvciBsZW5ndGggZXh0cmEgYml0cyAqLwogIHZhciBESVNUID0gMjM7IC8qIGk6IHdhaXRpbmcgZm9yIGRpc3RhbmNlIGNvZGUgKi8KICB2YXIgRElTVEVYVCA9IDI0OyAvKiBpOiB3YWl0aW5nIGZvciBkaXN0YW5jZSBleHRyYSBiaXRzICovCiAgdmFyIE1BVENIID0gMjU7IC8qIG86IHdhaXRpbmcgZm9yIG91dHB1dCBzcGFjZSB0byBjb3B5IHN0cmluZyAqLwogIHZhciBMSVQgPSAyNjsgLyogbzogd2FpdGluZyBmb3Igb3V0cHV0IHNwYWNlIHRvIHdyaXRlIGxpdGVyYWwgKi8KICB2YXIgQ0hFQ0sgPSAyNzsgLyogaTogd2FpdGluZyBmb3IgMzItYml0IGNoZWNrIHZhbHVlICovCiAgdmFyIExFTkdUSCA9IDI4OyAvKiBpOiB3YWl0aW5nIGZvciAzMi1iaXQgbGVuZ3RoIChnemlwKSAqLwogIHZhciBET05FID0gMjk7IC8qIGZpbmlzaGVkIGNoZWNrLCBkb25lIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovCiAgdmFyIEJBRCA9IDMwOyAvKiBnb3QgYSBkYXRhIGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovCiAgdmFyIE1FTSA9IDMxOyAvKiBnb3QgYW4gaW5mbGF0ZSgpIG1lbW9yeSBlcnJvciAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqLwogIHZhciBTWU5DID0gMzI7IC8qIGxvb2tpbmcgZm9yIHN5bmNocm9uaXphdGlvbiBieXRlcyB0byByZXN0YXJ0IGluZmxhdGUoKSAqLwoKICAvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKICB2YXIgRU5PVUdIX0xFTlMgPSA4NTI7CiAgdmFyIEVOT1VHSF9ESVNUUyA9IDU5MjsKICAvL2NvbnN0IEVOT1VHSCA9ICAoRU5PVUdIX0xFTlMrRU5PVUdIX0RJU1RTKTsKCiAgdmFyIE1BWF9XQklUUyA9IDE1OwogIC8qIDMySyBMWjc3IHdpbmRvdyAqLwogIHZhciBERUZfV0JJVFMgPSBNQVhfV0JJVFM7CiAgdmFyIHpzd2FwMzIgPSBmdW5jdGlvbiB6c3dhcDMyKHEpIHsKICAgIHJldHVybiAocSA+Pj4gMjQgJiAweGZmKSArIChxID4+PiA4ICYgMHhmZjAwKSArICgocSAmIDB4ZmYwMCkgPDwgOCkgKyAoKHEgJiAweGZmKSA8PCAyNCk7CiAgfTsKICBmdW5jdGlvbiBJbmZsYXRlU3RhdGUoKSB7CiAgICB0aGlzLm1vZGUgPSAwOyAvKiBjdXJyZW50IGluZmxhdGUgbW9kZSAqLwogICAgdGhpcy5sYXN0ID0gZmFsc2U7IC8qIHRydWUgaWYgcHJvY2Vzc2luZyBsYXN0IGJsb2NrICovCiAgICB0aGlzLndyYXAgPSAwOyAvKiBiaXQgMCB0cnVlIGZvciB6bGliLCBiaXQgMSB0cnVlIGZvciBnemlwICovCiAgICB0aGlzLmhhdmVkaWN0ID0gZmFsc2U7IC8qIHRydWUgaWYgZGljdGlvbmFyeSBwcm92aWRlZCAqLwogICAgdGhpcy5mbGFncyA9IDA7IC8qIGd6aXAgaGVhZGVyIG1ldGhvZCBhbmQgZmxhZ3MgKDAgaWYgemxpYikgKi8KICAgIHRoaXMuZG1heCA9IDA7IC8qIHpsaWIgaGVhZGVyIG1heCBkaXN0YW5jZSAoSU5GTEFURV9TVFJJQ1QpICovCiAgICB0aGlzLmNoZWNrID0gMDsgLyogcHJvdGVjdGVkIGNvcHkgb2YgY2hlY2sgdmFsdWUgKi8KICAgIHRoaXMudG90YWwgPSAwOyAvKiBwcm90ZWN0ZWQgY29weSBvZiBvdXRwdXQgY291bnQgKi8KICAgIC8vIFRPRE86IG1heSBiZSB7fQogICAgdGhpcy5oZWFkID0gbnVsbDsgLyogd2hlcmUgdG8gc2F2ZSBnemlwIGhlYWRlciBpbmZvcm1hdGlvbiAqLwoKICAgIC8qIHNsaWRpbmcgd2luZG93ICovCiAgICB0aGlzLndiaXRzID0gMDsgLyogbG9nIGJhc2UgMiBvZiByZXF1ZXN0ZWQgd2luZG93IHNpemUgKi8KICAgIHRoaXMud3NpemUgPSAwOyAvKiB3aW5kb3cgc2l6ZSBvciB6ZXJvIGlmIG5vdCB1c2luZyB3aW5kb3cgKi8KICAgIHRoaXMud2hhdmUgPSAwOyAvKiB2YWxpZCBieXRlcyBpbiB0aGUgd2luZG93ICovCiAgICB0aGlzLnduZXh0ID0gMDsgLyogd2luZG93IHdyaXRlIGluZGV4ICovCiAgICB0aGlzLndpbmRvdyA9IG51bGw7IC8qIGFsbG9jYXRlZCBzbGlkaW5nIHdpbmRvdywgaWYgbmVlZGVkICovCgogICAgLyogYml0IGFjY3VtdWxhdG9yICovCiAgICB0aGlzLmhvbGQgPSAwOyAvKiBpbnB1dCBiaXQgYWNjdW11bGF0b3IgKi8KICAgIHRoaXMuYml0cyA9IDA7IC8qIG51bWJlciBvZiBiaXRzIGluICJpbiIgKi8KCiAgICAvKiBmb3Igc3RyaW5nIGFuZCBzdG9yZWQgYmxvY2sgY29weWluZyAqLwogICAgdGhpcy5sZW5ndGggPSAwOyAvKiBsaXRlcmFsIG9yIGxlbmd0aCBvZiBkYXRhIHRvIGNvcHkgKi8KICAgIHRoaXMub2Zmc2V0ID0gMDsgLyogZGlzdGFuY2UgYmFjayB0byBjb3B5IHN0cmluZyBmcm9tICovCgogICAgLyogZm9yIHRhYmxlIGFuZCBjb2RlIGRlY29kaW5nICovCiAgICB0aGlzLmV4dHJhID0gMDsgLyogZXh0cmEgYml0cyBuZWVkZWQgKi8KCiAgICAvKiBmaXhlZCBhbmQgZHluYW1pYyBjb2RlIHRhYmxlcyAqLwogICAgdGhpcy5sZW5jb2RlID0gbnVsbDsgLyogc3RhcnRpbmcgdGFibGUgZm9yIGxlbmd0aC9saXRlcmFsIGNvZGVzICovCiAgICB0aGlzLmRpc3Rjb2RlID0gbnVsbDsgLyogc3RhcnRpbmcgdGFibGUgZm9yIGRpc3RhbmNlIGNvZGVzICovCiAgICB0aGlzLmxlbmJpdHMgPSAwOyAvKiBpbmRleCBiaXRzIGZvciBsZW5jb2RlICovCiAgICB0aGlzLmRpc3RiaXRzID0gMDsgLyogaW5kZXggYml0cyBmb3IgZGlzdGNvZGUgKi8KCiAgICAvKiBkeW5hbWljIHRhYmxlIGJ1aWxkaW5nICovCiAgICB0aGlzLm5jb2RlID0gMDsgLyogbnVtYmVyIG9mIGNvZGUgbGVuZ3RoIGNvZGUgbGVuZ3RocyAqLwogICAgdGhpcy5ubGVuID0gMDsgLyogbnVtYmVyIG9mIGxlbmd0aCBjb2RlIGxlbmd0aHMgKi8KICAgIHRoaXMubmRpc3QgPSAwOyAvKiBudW1iZXIgb2YgZGlzdGFuY2UgY29kZSBsZW5ndGhzICovCiAgICB0aGlzLmhhdmUgPSAwOyAvKiBudW1iZXIgb2YgY29kZSBsZW5ndGhzIGluIGxlbnNbXSAqLwogICAgdGhpcy5uZXh0ID0gbnVsbDsgLyogbmV4dCBhdmFpbGFibGUgc3BhY2UgaW4gY29kZXNbXSAqLwoKICAgIHRoaXMubGVucyA9IG5ldyBVaW50MTZBcnJheSgzMjApOyAvKiB0ZW1wb3Jhcnkgc3RvcmFnZSBmb3IgY29kZSBsZW5ndGhzICovCiAgICB0aGlzLndvcmsgPSBuZXcgVWludDE2QXJyYXkoMjg4KTsgLyogd29yayBhcmVhIGZvciBjb2RlIHRhYmxlIGJ1aWxkaW5nICovCgogICAgLyoKICAgICBiZWNhdXNlIHdlIGRvbid0IGhhdmUgcG9pbnRlcnMgaW4ganMsIHdlIHVzZSBsZW5jb2RlIGFuZCBkaXN0Y29kZSBkaXJlY3RseQogICAgIGFzIGJ1ZmZlcnMgc28gd2UgZG9uJ3QgbmVlZCBjb2RlcwogICAgKi8KICAgIC8vdGhpcy5jb2RlcyA9IG5ldyBJbnQzMkFycmF5KEVOT1VHSCk7ICAgICAgIC8qIHNwYWNlIGZvciBjb2RlIHRhYmxlcyAqLwogICAgdGhpcy5sZW5keW4gPSBudWxsOyAvKiBkeW5hbWljIHRhYmxlIGZvciBsZW5ndGgvbGl0ZXJhbCBjb2RlcyAoSlMgc3BlY2lmaWMpICovCiAgICB0aGlzLmRpc3RkeW4gPSBudWxsOyAvKiBkeW5hbWljIHRhYmxlIGZvciBkaXN0YW5jZSBjb2RlcyAoSlMgc3BlY2lmaWMpICovCiAgICB0aGlzLnNhbmUgPSAwOyAvKiBpZiBmYWxzZSwgYWxsb3cgaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyICovCiAgICB0aGlzLmJhY2sgPSAwOyAvKiBiaXRzIGJhY2sgb2YgbGFzdCB1bnByb2Nlc3NlZCBsZW5ndGgvbGl0ICovCiAgICB0aGlzLndhcyA9IDA7IC8qIGluaXRpYWwgbGVuZ3RoIG9mIG1hdGNoICovCiAgfQogIHZhciBpbmZsYXRlUmVzZXRLZWVwID0gZnVuY3Rpb24gaW5mbGF0ZVJlc2V0S2VlcChzdHJtKSB7CiAgICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsKICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7CiAgICB9CiAgICB2YXIgc3RhdGUgPSBzdHJtLnN0YXRlOwogICAgc3RybS50b3RhbF9pbiA9IHN0cm0udG90YWxfb3V0ID0gc3RhdGUudG90YWwgPSAwOwogICAgc3RybS5tc2cgPSAnJzsgLypaX05VTEwqLwogICAgaWYgKHN0YXRlLndyYXApIHsKICAgICAgLyogdG8gc3VwcG9ydCBpbGwtY29uY2VpdmVkIEphdmEgdGVzdCBzdWl0ZSAqLwogICAgICBzdHJtLmFkbGVyID0gc3RhdGUud3JhcCAmIDE7CiAgICB9CiAgICBzdGF0ZS5tb2RlID0gSEVBRDsKICAgIHN0YXRlLmxhc3QgPSAwOwogICAgc3RhdGUuaGF2ZWRpY3QgPSAwOwogICAgc3RhdGUuZG1heCA9IDMyNzY4OwogICAgc3RhdGUuaGVhZCA9IG51bGwgLypaX05VTEwqLzsKICAgIHN0YXRlLmhvbGQgPSAwOwogICAgc3RhdGUuYml0cyA9IDA7CiAgICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLm5leHQgPSBzdGF0ZS5jb2RlczsKICAgIHN0YXRlLmxlbmNvZGUgPSBzdGF0ZS5sZW5keW4gPSBuZXcgSW50MzJBcnJheShFTk9VR0hfTEVOUyk7CiAgICBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLmRpc3RkeW4gPSBuZXcgSW50MzJBcnJheShFTk9VR0hfRElTVFMpOwogICAgc3RhdGUuc2FuZSA9IDE7CiAgICBzdGF0ZS5iYWNrID0gLTE7CiAgICAvL1RyYWNldigoc3RkZXJyLCAiaW5mbGF0ZTogcmVzZXRcbiIpKTsKICAgIHJldHVybiBaX09LJDE7CiAgfTsKICB2YXIgaW5mbGF0ZVJlc2V0ID0gZnVuY3Rpb24gaW5mbGF0ZVJlc2V0KHN0cm0pIHsKICAgIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTsKICAgIH0KICAgIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7CiAgICBzdGF0ZS53c2l6ZSA9IDA7CiAgICBzdGF0ZS53aGF2ZSA9IDA7CiAgICBzdGF0ZS53bmV4dCA9IDA7CiAgICByZXR1cm4gaW5mbGF0ZVJlc2V0S2VlcChzdHJtKTsKICB9OwogIHZhciBpbmZsYXRlUmVzZXQyID0gZnVuY3Rpb24gaW5mbGF0ZVJlc2V0MihzdHJtLCB3aW5kb3dCaXRzKSB7CiAgICB2YXIgd3JhcDsKCiAgICAvKiBnZXQgdGhlIHN0YXRlICovCiAgICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsKICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7CiAgICB9CiAgICB2YXIgc3RhdGUgPSBzdHJtLnN0YXRlOwoKICAgIC8qIGV4dHJhY3Qgd3JhcCByZXF1ZXN0IGZyb20gd2luZG93Qml0cyBwYXJhbWV0ZXIgKi8KICAgIGlmICh3aW5kb3dCaXRzIDwgMCkgewogICAgICB3cmFwID0gMDsKICAgICAgd2luZG93Qml0cyA9IC13aW5kb3dCaXRzOwogICAgfSBlbHNlIHsKICAgICAgd3JhcCA9ICh3aW5kb3dCaXRzID4+IDQpICsgMTsKICAgICAgaWYgKHdpbmRvd0JpdHMgPCA0OCkgewogICAgICAgIHdpbmRvd0JpdHMgJj0gMTU7CiAgICAgIH0KICAgIH0KCiAgICAvKiBzZXQgbnVtYmVyIG9mIHdpbmRvdyBiaXRzLCBmcmVlIHdpbmRvdyBpZiBkaWZmZXJlbnQgKi8KICAgIGlmICh3aW5kb3dCaXRzICYmICh3aW5kb3dCaXRzIDwgOCB8fCB3aW5kb3dCaXRzID4gMTUpKSB7CiAgICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUiQxOwogICAgfQogICAgaWYgKHN0YXRlLndpbmRvdyAhPT0gbnVsbCAmJiBzdGF0ZS53Yml0cyAhPT0gd2luZG93Qml0cykgewogICAgICBzdGF0ZS53aW5kb3cgPSBudWxsOwogICAgfQoKICAgIC8qIHVwZGF0ZSBzdGF0ZSBhbmQgcmVzZXQgdGhlIHJlc3Qgb2YgaXQgKi8KICAgIHN0YXRlLndyYXAgPSB3cmFwOwogICAgc3RhdGUud2JpdHMgPSB3aW5kb3dCaXRzOwogICAgcmV0dXJuIGluZmxhdGVSZXNldChzdHJtKTsKICB9OwogIHZhciBpbmZsYXRlSW5pdDIgPSBmdW5jdGlvbiBpbmZsYXRlSW5pdDIoc3RybSwgd2luZG93Qml0cykgewogICAgaWYgKCFzdHJtKSB7CiAgICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUiQxOwogICAgfQogICAgLy9zdHJtLm1zZyA9IFpfTlVMTDsgICAgICAgICAgICAgICAgIC8qIGluIGNhc2Ugd2UgcmV0dXJuIGFuIGVycm9yICovCgogICAgdmFyIHN0YXRlID0gbmV3IEluZmxhdGVTdGF0ZSgpOwoKICAgIC8vaWYgKHN0YXRlID09PSBaX05VTEwpIHJldHVybiBaX01FTV9FUlJPUjsKICAgIC8vVHJhY2V2KChzdGRlcnIsICJpbmZsYXRlOiBhbGxvY2F0ZWRcbiIpKTsKICAgIHN0cm0uc3RhdGUgPSBzdGF0ZTsKICAgIHN0YXRlLndpbmRvdyA9IG51bGwgLypaX05VTEwqLzsKICAgIHZhciByZXQgPSBpbmZsYXRlUmVzZXQyKHN0cm0sIHdpbmRvd0JpdHMpOwogICAgaWYgKHJldCAhPT0gWl9PSyQxKSB7CiAgICAgIHN0cm0uc3RhdGUgPSBudWxsIC8qWl9OVUxMKi87CiAgICB9CiAgICByZXR1cm4gcmV0OwogIH07CiAgdmFyIGluZmxhdGVJbml0ID0gZnVuY3Rpb24gaW5mbGF0ZUluaXQoc3RybSkgewogICAgcmV0dXJuIGluZmxhdGVJbml0MihzdHJtLCBERUZfV0JJVFMpOwogIH07CgogIC8qCiAgIFJldHVybiBzdGF0ZSB3aXRoIGxlbmd0aCBhbmQgZGlzdGFuY2UgZGVjb2RpbmcgdGFibGVzIGFuZCBpbmRleCBzaXplcyBzZXQgdG8KICAgZml4ZWQgY29kZSBkZWNvZGluZy4gIE5vcm1hbGx5IHRoaXMgcmV0dXJucyBmaXhlZCB0YWJsZXMgZnJvbSBpbmZmaXhlZC5oLgogICBJZiBCVUlMREZJWEVEIGlzIGRlZmluZWQsIHRoZW4gaW5zdGVhZCB0aGlzIHJvdXRpbmUgYnVpbGRzIHRoZSB0YWJsZXMgdGhlCiAgIGZpcnN0IHRpbWUgaXQncyBjYWxsZWQsIGFuZCByZXR1cm5zIHRob3NlIHRhYmxlcyB0aGUgZmlyc3QgdGltZSBhbmQKICAgdGhlcmVhZnRlci4gIFRoaXMgcmVkdWNlcyB0aGUgc2l6ZSBvZiB0aGUgY29kZSBieSBhYm91dCAySyBieXRlcywgaW4KICAgZXhjaGFuZ2UgZm9yIGEgbGl0dGxlIGV4ZWN1dGlvbiB0aW1lLiAgSG93ZXZlciwgQlVJTERGSVhFRCBzaG91bGQgbm90IGJlCiAgIHVzZWQgZm9yIHRocmVhZGVkIGFwcGxpY2F0aW9ucywgc2luY2UgdGhlIHJld3JpdGluZyBvZiB0aGUgdGFibGVzIGFuZCB2aXJnaW4KICAgbWF5IG5vdCBiZSB0aHJlYWQtc2FmZS4KICAgKi8KICB2YXIgdmlyZ2luID0gdHJ1ZTsKICB2YXIgbGVuZml4LCBkaXN0Zml4OyAvLyBXZSBoYXZlIG5vIHBvaW50ZXJzIGluIEpTLCBzbyBrZWVwIHRhYmxlcyBzZXBhcmF0ZQoKICB2YXIgZml4ZWR0YWJsZXMgPSBmdW5jdGlvbiBmaXhlZHRhYmxlcyhzdGF0ZSkgewogICAgLyogYnVpbGQgZml4ZWQgaHVmZm1hbiB0YWJsZXMgaWYgZmlyc3QgY2FsbCAobWF5IG5vdCBiZSB0aHJlYWQgc2FmZSkgKi8KICAgIGlmICh2aXJnaW4pIHsKICAgICAgbGVuZml4ID0gbmV3IEludDMyQXJyYXkoNTEyKTsKICAgICAgZGlzdGZpeCA9IG5ldyBJbnQzMkFycmF5KDMyKTsKCiAgICAgIC8qIGxpdGVyYWwvbGVuZ3RoIHRhYmxlICovCiAgICAgIHZhciBzeW0gPSAwOwogICAgICB3aGlsZSAoc3ltIDwgMTQ0KSB7CiAgICAgICAgc3RhdGUubGVuc1tzeW0rK10gPSA4OwogICAgICB9CiAgICAgIHdoaWxlIChzeW0gPCAyNTYpIHsKICAgICAgICBzdGF0ZS5sZW5zW3N5bSsrXSA9IDk7CiAgICAgIH0KICAgICAgd2hpbGUgKHN5bSA8IDI4MCkgewogICAgICAgIHN0YXRlLmxlbnNbc3ltKytdID0gNzsKICAgICAgfQogICAgICB3aGlsZSAoc3ltIDwgMjg4KSB7CiAgICAgICAgc3RhdGUubGVuc1tzeW0rK10gPSA4OwogICAgICB9CiAgICAgIGluZmxhdGVfdGFibGUoTEVOUywgc3RhdGUubGVucywgMCwgMjg4LCBsZW5maXgsIDAsIHN0YXRlLndvcmssIHsKICAgICAgICBiaXRzOiA5CiAgICAgIH0pOwoKICAgICAgLyogZGlzdGFuY2UgdGFibGUgKi8KICAgICAgc3ltID0gMDsKICAgICAgd2hpbGUgKHN5bSA8IDMyKSB7CiAgICAgICAgc3RhdGUubGVuc1tzeW0rK10gPSA1OwogICAgICB9CiAgICAgIGluZmxhdGVfdGFibGUoRElTVFMsIHN0YXRlLmxlbnMsIDAsIDMyLCBkaXN0Zml4LCAwLCBzdGF0ZS53b3JrLCB7CiAgICAgICAgYml0czogNQogICAgICB9KTsKCiAgICAgIC8qIGRvIHRoaXMganVzdCBvbmNlICovCiAgICAgIHZpcmdpbiA9IGZhbHNlOwogICAgfQogICAgc3RhdGUubGVuY29kZSA9IGxlbmZpeDsKICAgIHN0YXRlLmxlbmJpdHMgPSA5OwogICAgc3RhdGUuZGlzdGNvZGUgPSBkaXN0Zml4OwogICAgc3RhdGUuZGlzdGJpdHMgPSA1OwogIH07CgogIC8qCiAgIFVwZGF0ZSB0aGUgd2luZG93IHdpdGggdGhlIGxhc3Qgd3NpemUgKG5vcm1hbGx5IDMySykgYnl0ZXMgd3JpdHRlbiBiZWZvcmUKICAgcmV0dXJuaW5nLiAgSWYgd2luZG93IGRvZXMgbm90IGV4aXN0IHlldCwgY3JlYXRlIGl0LiAgVGhpcyBpcyBvbmx5IGNhbGxlZAogICB3aGVuIGEgd2luZG93IGlzIGFscmVhZHkgaW4gdXNlLCBvciB3aGVuIG91dHB1dCBoYXMgYmVlbiB3cml0dGVuIGR1cmluZyB0aGlzCiAgIGluZmxhdGUgY2FsbCwgYnV0IHRoZSBlbmQgb2YgdGhlIGRlZmxhdGUgc3RyZWFtIGhhcyBub3QgYmVlbiByZWFjaGVkIHlldC4KICAgSXQgaXMgYWxzbyBjYWxsZWQgdG8gY3JlYXRlIGEgd2luZG93IGZvciBkaWN0aW9uYXJ5IGRhdGEgd2hlbiBhIGRpY3Rpb25hcnkKICAgaXMgbG9hZGVkLgoKICAgUHJvdmlkaW5nIG91dHB1dCBidWZmZXJzIGxhcmdlciB0aGFuIDMySyB0byBpbmZsYXRlKCkgc2hvdWxkIHByb3ZpZGUgYSBzcGVlZAogICBhZHZhbnRhZ2UsIHNpbmNlIG9ubHkgdGhlIGxhc3QgMzJLIG9mIG91dHB1dCBpcyBjb3BpZWQgdG8gdGhlIHNsaWRpbmcgd2luZG93CiAgIHVwb24gcmV0dXJuIGZyb20gaW5mbGF0ZSgpLCBhbmQgc2luY2UgYWxsIGRpc3RhbmNlcyBhZnRlciB0aGUgZmlyc3QgMzJLIG9mCiAgIG91dHB1dCB3aWxsIGZhbGwgaW4gdGhlIG91dHB1dCBkYXRhLCBtYWtpbmcgbWF0Y2ggY29waWVzIHNpbXBsZXIgYW5kIGZhc3Rlci4KICAgVGhlIGFkdmFudGFnZSBtYXkgYmUgZGVwZW5kZW50IG9uIHRoZSBzaXplIG9mIHRoZSBwcm9jZXNzb3IncyBkYXRhIGNhY2hlcy4KICAgKi8KICB2YXIgdXBkYXRld2luZG93ID0gZnVuY3Rpb24gdXBkYXRld2luZG93KHN0cm0sIHNyYywgZW5kLCBjb3B5KSB7CiAgICB2YXIgZGlzdDsKICAgIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7CgogICAgLyogaWYgaXQgaGFzbid0IGJlZW4gZG9uZSBhbHJlYWR5LCBhbGxvY2F0ZSBzcGFjZSBmb3IgdGhlIHdpbmRvdyAqLwogICAgaWYgKHN0YXRlLndpbmRvdyA9PT0gbnVsbCkgewogICAgICBzdGF0ZS53c2l6ZSA9IDEgPDwgc3RhdGUud2JpdHM7CiAgICAgIHN0YXRlLnduZXh0ID0gMDsKICAgICAgc3RhdGUud2hhdmUgPSAwOwogICAgICBzdGF0ZS53aW5kb3cgPSBuZXcgVWludDhBcnJheShzdGF0ZS53c2l6ZSk7CiAgICB9CgogICAgLyogY29weSBzdGF0ZS0+d3NpemUgb3IgbGVzcyBvdXRwdXQgYnl0ZXMgaW50byB0aGUgY2lyY3VsYXIgd2luZG93ICovCiAgICBpZiAoY29weSA+PSBzdGF0ZS53c2l6ZSkgewogICAgICBzdGF0ZS53aW5kb3cuc2V0KHNyYy5zdWJhcnJheShlbmQgLSBzdGF0ZS53c2l6ZSwgZW5kKSwgMCk7CiAgICAgIHN0YXRlLnduZXh0ID0gMDsKICAgICAgc3RhdGUud2hhdmUgPSBzdGF0ZS53c2l6ZTsKICAgIH0gZWxzZSB7CiAgICAgIGRpc3QgPSBzdGF0ZS53c2l6ZSAtIHN0YXRlLnduZXh0OwogICAgICBpZiAoZGlzdCA+IGNvcHkpIHsKICAgICAgICBkaXN0ID0gY29weTsKICAgICAgfQogICAgICAvL3ptZW1jcHkoc3RhdGUtPndpbmRvdyArIHN0YXRlLT53bmV4dCwgZW5kIC0gY29weSwgZGlzdCk7CiAgICAgIHN0YXRlLndpbmRvdy5zZXQoc3JjLnN1YmFycmF5KGVuZCAtIGNvcHksIGVuZCAtIGNvcHkgKyBkaXN0KSwgc3RhdGUud25leHQpOwogICAgICBjb3B5IC09IGRpc3Q7CiAgICAgIGlmIChjb3B5KSB7CiAgICAgICAgLy96bWVtY3B5KHN0YXRlLT53aW5kb3csIGVuZCAtIGNvcHksIGNvcHkpOwogICAgICAgIHN0YXRlLndpbmRvdy5zZXQoc3JjLnN1YmFycmF5KGVuZCAtIGNvcHksIGVuZCksIDApOwogICAgICAgIHN0YXRlLnduZXh0ID0gY29weTsKICAgICAgICBzdGF0ZS53aGF2ZSA9IHN0YXRlLndzaXplOwogICAgICB9IGVsc2UgewogICAgICAgIHN0YXRlLnduZXh0ICs9IGRpc3Q7CiAgICAgICAgaWYgKHN0YXRlLnduZXh0ID09PSBzdGF0ZS53c2l6ZSkgewogICAgICAgICAgc3RhdGUud25leHQgPSAwOwogICAgICAgIH0KICAgICAgICBpZiAoc3RhdGUud2hhdmUgPCBzdGF0ZS53c2l6ZSkgewogICAgICAgICAgc3RhdGUud2hhdmUgKz0gZGlzdDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwogIH07CiAgdmFyIGluZmxhdGUkMiA9IGZ1bmN0aW9uIGluZmxhdGUoc3RybSwgZmx1c2gpIHsKICAgIHZhciBzdGF0ZTsKICAgIHZhciBpbnB1dCwgb3V0cHV0OyAvLyBpbnB1dC9vdXRwdXQgYnVmZmVycwogICAgdmFyIG5leHQ7IC8qIG5leHQgaW5wdXQgSU5ERVggKi8KICAgIHZhciBwdXQ7IC8qIG5leHQgb3V0cHV0IElOREVYICovCiAgICB2YXIgaGF2ZSwgbGVmdDsgLyogYXZhaWxhYmxlIGlucHV0IGFuZCBvdXRwdXQgKi8KICAgIHZhciBob2xkOyAvKiBiaXQgYnVmZmVyICovCiAgICB2YXIgYml0czsgLyogYml0cyBpbiBiaXQgYnVmZmVyICovCiAgICB2YXIgX2luLCBfb3V0OyAvKiBzYXZlIHN0YXJ0aW5nIGF2YWlsYWJsZSBpbnB1dCBhbmQgb3V0cHV0ICovCiAgICB2YXIgY29weTsgLyogbnVtYmVyIG9mIHN0b3JlZCBvciBtYXRjaCBieXRlcyB0byBjb3B5ICovCiAgICB2YXIgZnJvbTsgLyogd2hlcmUgdG8gY29weSBtYXRjaCBieXRlcyBmcm9tICovCiAgICB2YXIgZnJvbV9zb3VyY2U7CiAgICB2YXIgaGVyZSA9IDA7IC8qIGN1cnJlbnQgZGVjb2RpbmcgdGFibGUgZW50cnkgKi8KICAgIHZhciBoZXJlX2JpdHMsIGhlcmVfb3AsIGhlcmVfdmFsOyAvLyBwYWtlZCAiaGVyZSIgZGVub3JtYWxpemVkIChKUyBzcGVjaWZpYykKICAgIC8vbGV0IGxhc3Q7ICAgICAgICAgICAgICAgICAgIC8qIHBhcmVudCB0YWJsZSBlbnRyeSAqLwogICAgdmFyIGxhc3RfYml0cywgbGFzdF9vcCwgbGFzdF92YWw7IC8vIHBha2VkICJsYXN0IiBkZW5vcm1hbGl6ZWQgKEpTIHNwZWNpZmljKQogICAgdmFyIGxlbjsgLyogbGVuZ3RoIHRvIGNvcHkgZm9yIHJlcGVhdHMsIGJpdHMgdG8gZHJvcCAqLwogICAgdmFyIHJldDsgLyogcmV0dXJuIGNvZGUgKi8KICAgIHZhciBoYnVmID0gbmV3IFVpbnQ4QXJyYXkoNCk7IC8qIGJ1ZmZlciBmb3IgZ3ppcCBoZWFkZXIgY3JjIGNhbGN1bGF0aW9uICovCiAgICB2YXIgb3B0czsKICAgIHZhciBuOyAvLyB0ZW1wb3JhcnkgdmFyaWFibGUgZm9yIE5FRURfQklUUwoKICAgIHZhciBvcmRlciA9IC8qIHBlcm11dGF0aW9uIG9mIGNvZGUgbGVuZ3RocyAqLwogICAgbmV3IFVpbnQ4QXJyYXkoWzE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTVdKTsKICAgIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSB8fCAhc3RybS5vdXRwdXQgfHwgIXN0cm0uaW5wdXQgJiYgc3RybS5hdmFpbF9pbiAhPT0gMCkgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTsKICAgIH0KICAgIHN0YXRlID0gc3RybS5zdGF0ZTsKICAgIGlmIChzdGF0ZS5tb2RlID09PSBUWVBFKSB7CiAgICAgIHN0YXRlLm1vZGUgPSBUWVBFRE87CiAgICB9IC8qIHNraXAgY2hlY2sgKi8KCiAgICAvLy0tLSBMT0FEKCkgLS0tCiAgICBwdXQgPSBzdHJtLm5leHRfb3V0OwogICAgb3V0cHV0ID0gc3RybS5vdXRwdXQ7CiAgICBsZWZ0ID0gc3RybS5hdmFpbF9vdXQ7CiAgICBuZXh0ID0gc3RybS5uZXh0X2luOwogICAgaW5wdXQgPSBzdHJtLmlucHV0OwogICAgaGF2ZSA9IHN0cm0uYXZhaWxfaW47CiAgICBob2xkID0gc3RhdGUuaG9sZDsKICAgIGJpdHMgPSBzdGF0ZS5iaXRzOwogICAgLy8tLS0KCiAgICBfaW4gPSBoYXZlOwogICAgX291dCA9IGxlZnQ7CiAgICByZXQgPSBaX09LJDE7CiAgICBpbmZfbGVhdmU6CiAgICAvLyBnb3RvIGVtdWxhdGlvbgogICAgZm9yICg7OykgewogICAgICBzd2l0Y2ggKHN0YXRlLm1vZGUpIHsKICAgICAgICBjYXNlIEhFQUQ6CiAgICAgICAgICBpZiAoc3RhdGUud3JhcCA9PT0gMCkgewogICAgICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRURPOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsKICAgICAgICAgIHdoaWxlIChiaXRzIDwgMTYpIHsKICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsKICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaGF2ZS0tOwogICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0czsKICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgfQogICAgICAgICAgLy89PT0vLwogICAgICAgICAgaWYgKHN0YXRlLndyYXAgJiAyICYmIGhvbGQgPT09IDB4OGIxZikgewogICAgICAgICAgICAvKiBnemlwIGhlYWRlciAqLwogICAgICAgICAgICBzdGF0ZS5jaGVjayA9IDAgLypjcmMzMigwTCwgWl9OVUxMLCAwKSovOwogICAgICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTsKICAgICAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmOwogICAgICAgICAgICBoYnVmWzFdID0gaG9sZCA+Pj4gOCAmIDB4ZmY7CiAgICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGhidWYsIDIsIDApOwogICAgICAgICAgICAvLz09PS8vCgogICAgICAgICAgICAvLz09PSBJTklUQklUUygpOwogICAgICAgICAgICBob2xkID0gMDsKICAgICAgICAgICAgYml0cyA9IDA7CiAgICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgICAgc3RhdGUubW9kZSA9IEZMQUdTOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIHN0YXRlLmZsYWdzID0gMDsgLyogZXhwZWN0IHpsaWIgaGVhZGVyICovCiAgICAgICAgICBpZiAoc3RhdGUuaGVhZCkgewogICAgICAgICAgICBzdGF0ZS5oZWFkLmRvbmUgPSBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghKHN0YXRlLndyYXAgJiAxKSB8fCAvKiBjaGVjayBpZiB6bGliIGhlYWRlciBhbGxvd2VkICovCiAgICAgICAgICAoKChob2xkICYgMHhmZiAvKkJJVFMoOCkqLykgPDwgOCkgKyAoaG9sZCA+PiA4KSkgJSAzMSkgewogICAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgaGVhZGVyIGNoZWNrJzsKICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKGhvbGQgJiAweDBmIC8qQklUUyg0KSovKSAhPT0gWl9ERUZMQVRFRCkgewogICAgICAgICAgICBzdHJtLm1zZyA9ICd1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCc7CiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgLy8tLS0gRFJPUEJJVFMoNCkgLS0tLy8KICAgICAgICAgIGhvbGQgPj4+PSA0OwogICAgICAgICAgYml0cyAtPSA0OwogICAgICAgICAgLy8tLS0vLwogICAgICAgICAgbGVuID0gKGhvbGQgJiAweDBmIC8qQklUUyg0KSovKSArIDg7CiAgICAgICAgICBpZiAoc3RhdGUud2JpdHMgPT09IDApIHsKICAgICAgICAgICAgc3RhdGUud2JpdHMgPSBsZW47CiAgICAgICAgICB9IGVsc2UgaWYgKGxlbiA+IHN0YXRlLndiaXRzKSB7CiAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgd2luZG93IHNpemUnOwogICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyAhISEgcGFrbyBwYXRjaC4gRm9yY2UgdXNlIGBvcHRpb25zLndpbmRvd0JpdHNgIGlmIHBhc3NlZC4KICAgICAgICAgIC8vIFJlcXVpcmVkIHRvIGFsd2F5cyB1c2UgbWF4IHdpbmRvdyBzaXplIGJ5IGRlZmF1bHQuCiAgICAgICAgICBzdGF0ZS5kbWF4ID0gMSA8PCBzdGF0ZS53Yml0czsKICAgICAgICAgIC8vc3RhdGUuZG1heCA9IDEgPDwgbGVuOwoKICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsICJpbmZsYXRlOiAgIHpsaWIgaGVhZGVyIG9rXG4iKSk7CiAgICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAxIC8qYWRsZXIzMigwTCwgWl9OVUxMLCAwKSovOwogICAgICAgICAgc3RhdGUubW9kZSA9IGhvbGQgJiAweDIwMCA/IERJQ1RJRCA6IFRZUEU7CiAgICAgICAgICAvLz09PSBJTklUQklUUygpOwogICAgICAgICAgaG9sZCA9IDA7CiAgICAgICAgICBiaXRzID0gMDsKICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRkxBR1M6CiAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovCiAgICAgICAgICB3aGlsZSAoYml0cyA8IDE2KSB7CiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhhdmUtLTsKICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgIH0KICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgIHN0YXRlLmZsYWdzID0gaG9sZDsKICAgICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgJiAweGZmKSAhPT0gWl9ERUZMQVRFRCkgewogICAgICAgICAgICBzdHJtLm1zZyA9ICd1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCc7CiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHhlMDAwKSB7CiAgICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gaGVhZGVyIGZsYWdzIHNldCc7CiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHsKICAgICAgICAgICAgc3RhdGUuaGVhZC50ZXh0ID0gaG9sZCA+PiA4ICYgMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkgewogICAgICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTsKICAgICAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmOwogICAgICAgICAgICBoYnVmWzFdID0gaG9sZCA+Pj4gOCAmIDB4ZmY7CiAgICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGhidWYsIDIsIDApOwogICAgICAgICAgICAvLz09PS8vCiAgICAgICAgICB9CiAgICAgICAgICAvLz09PSBJTklUQklUUygpOwogICAgICAgICAgaG9sZCA9IDA7CiAgICAgICAgICBiaXRzID0gMDsKICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgIHN0YXRlLm1vZGUgPSBUSU1FOwogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlIFRJTUU6CiAgICAgICAgICAvLz09PSBORUVEQklUUygzMik7ICovCiAgICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7CiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhhdmUtLTsKICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgIH0KICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgIGlmIChzdGF0ZS5oZWFkKSB7CiAgICAgICAgICAgIHN0YXRlLmhlYWQudGltZSA9IGhvbGQ7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHsKICAgICAgICAgICAgLy89PT0gQ1JDNChzdGF0ZS5jaGVjaywgaG9sZCkKICAgICAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmOwogICAgICAgICAgICBoYnVmWzFdID0gaG9sZCA+Pj4gOCAmIDB4ZmY7CiAgICAgICAgICAgIGhidWZbMl0gPSBob2xkID4+PiAxNiAmIDB4ZmY7CiAgICAgICAgICAgIGhidWZbM10gPSBob2xkID4+PiAyNCAmIDB4ZmY7CiAgICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGhidWYsIDQsIDApOwogICAgICAgICAgICAvLz09PQogICAgICAgICAgfQogICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTsKICAgICAgICAgIGhvbGQgPSAwOwogICAgICAgICAgYml0cyA9IDA7CiAgICAgICAgICAvLz09PS8vCiAgICAgICAgICBzdGF0ZS5tb2RlID0gT1M7CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgT1M6CiAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovCiAgICAgICAgICB3aGlsZSAoYml0cyA8IDE2KSB7CiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhhdmUtLTsKICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgIH0KICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgIGlmIChzdGF0ZS5oZWFkKSB7CiAgICAgICAgICAgIHN0YXRlLmhlYWQueGZsYWdzID0gaG9sZCAmIDB4ZmY7CiAgICAgICAgICAgIHN0YXRlLmhlYWQub3MgPSBob2xkID4+IDg7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHsKICAgICAgICAgICAgLy89PT0gQ1JDMihzdGF0ZS5jaGVjaywgaG9sZCk7CiAgICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjsKICAgICAgICAgICAgaGJ1ZlsxXSA9IGhvbGQgPj4+IDggJiAweGZmOwogICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTsKICAgICAgICAgICAgLy89PT0vLwogICAgICAgICAgfQogICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTsKICAgICAgICAgIGhvbGQgPSAwOwogICAgICAgICAgYml0cyA9IDA7CiAgICAgICAgICAvLz09PS8vCiAgICAgICAgICBzdGF0ZS5tb2RlID0gRVhMRU47CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgRVhMRU46CiAgICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHsKICAgICAgICAgICAgLy89PT0gTkVFREJJVFMoMTYpOyAqLwogICAgICAgICAgICB3aGlsZSAoYml0cyA8IDE2KSB7CiAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsKICAgICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaGF2ZS0tOwogICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLz09PS8vCiAgICAgICAgICAgIHN0YXRlLmxlbmd0aCA9IGhvbGQ7CiAgICAgICAgICAgIGlmIChzdGF0ZS5oZWFkKSB7CiAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYV9sZW4gPSBob2xkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkgewogICAgICAgICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpOwogICAgICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjsKICAgICAgICAgICAgICBoYnVmWzFdID0gaG9sZCA+Pj4gOCAmIDB4ZmY7CiAgICAgICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaGJ1ZiwgMiwgMCk7CiAgICAgICAgICAgICAgLy89PT0vLwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7CiAgICAgICAgICAgIGhvbGQgPSAwOwogICAgICAgICAgICBiaXRzID0gMDsKICAgICAgICAgICAgLy89PT0vLwogICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5oZWFkKSB7CiAgICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmEgPSBudWxsIC8qWl9OVUxMKi87CiAgICAgICAgICB9CiAgICAgICAgICBzdGF0ZS5tb2RlID0gRVhUUkE7CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgRVhUUkE6CiAgICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHsKICAgICAgICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDsKICAgICAgICAgICAgaWYgKGNvcHkgPiBoYXZlKSB7CiAgICAgICAgICAgICAgY29weSA9IGhhdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvcHkpIHsKICAgICAgICAgICAgICBpZiAoc3RhdGUuaGVhZCkgewogICAgICAgICAgICAgICAgbGVuID0gc3RhdGUuaGVhZC5leHRyYV9sZW4gLSBzdGF0ZS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAoIXN0YXRlLmhlYWQuZXh0cmEpIHsKICAgICAgICAgICAgICAgICAgLy8gVXNlIHVudHlwZWQgYXJyYXkgZm9yIG1vcmUgY29udmVuaWVudCBwcm9jZXNzaW5nIGxhdGVyCiAgICAgICAgICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmEgPSBuZXcgVWludDhBcnJheShzdGF0ZS5oZWFkLmV4dHJhX2xlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdGF0ZS5oZWFkLmV4dHJhLnNldChpbnB1dC5zdWJhcnJheShuZXh0LAogICAgICAgICAgICAgICAgLy8gZXh0cmEgZmllbGQgaXMgbGltaXRlZCB0byA2NTUzNiBieXRlcwogICAgICAgICAgICAgICAgLy8gLSBubyBuZWVkIGZvciBhZGRpdGlvbmFsIHNpemUgY2hlY2sKICAgICAgICAgICAgICAgIG5leHQgKyBjb3B5KSwgLypsZW4gKyBjb3B5ID4gc3RhdGUuaGVhZC5leHRyYV9tYXggLSBsZW4gPyBzdGF0ZS5oZWFkLmV4dHJhX21heCA6IGNvcHksKi8KICAgICAgICAgICAgICAgIGxlbik7CiAgICAgICAgICAgICAgICAvL3ptZW1jcHkoc3RhdGUuaGVhZC5leHRyYSArIGxlbiwgbmV4dCwKICAgICAgICAgICAgICAgIC8vICAgICAgICBsZW4gKyBjb3B5ID4gc3RhdGUuaGVhZC5leHRyYV9tYXggPwogICAgICAgICAgICAgICAgLy8gICAgICAgIHN0YXRlLmhlYWQuZXh0cmFfbWF4IC0gbGVuIDogY29weSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkgewogICAgICAgICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBoYXZlIC09IGNvcHk7CiAgICAgICAgICAgICAgbmV4dCArPSBjb3B5OwogICAgICAgICAgICAgIHN0YXRlLmxlbmd0aCAtPSBjb3B5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdGF0ZS5sZW5ndGgpIHsKICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHN0YXRlLmxlbmd0aCA9IDA7CiAgICAgICAgICBzdGF0ZS5tb2RlID0gTkFNRTsKICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovCiAgICAgICAgY2FzZSBOQU1FOgogICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwODAwKSB7CiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvcHkgPSAwOwogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgLy8gVE9ETzogMiBvciAxIGJ5dGVzPwogICAgICAgICAgICAgIGxlbiA9IGlucHV0W25leHQgKyBjb3B5KytdOwogICAgICAgICAgICAgIC8qIHVzZSBjb25zdGFudCBsaW1pdCBiZWNhdXNlIGluIGpzIHdlIHNob3VsZCBub3QgcHJlYWxsb2NhdGUgbWVtb3J5ICovCiAgICAgICAgICAgICAgaWYgKHN0YXRlLmhlYWQgJiYgbGVuICYmIHN0YXRlLmxlbmd0aCA8IDY1NTM2IC8qc3RhdGUuaGVhZC5uYW1lX21heCovKSB7CiAgICAgICAgICAgICAgICBzdGF0ZS5oZWFkLm5hbWUgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW4pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSB3aGlsZSAobGVuICYmIGNvcHkgPCBoYXZlKTsKICAgICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7CiAgICAgICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhhdmUgLT0gY29weTsKICAgICAgICAgICAgbmV4dCArPSBjb3B5OwogICAgICAgICAgICBpZiAobGVuKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgaWYgKHN0YXRlLmhlYWQpIHsKICAgICAgICAgICAgc3RhdGUuaGVhZC5uYW1lID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHN0YXRlLmxlbmd0aCA9IDA7CiAgICAgICAgICBzdGF0ZS5tb2RlID0gQ09NTUVOVDsKICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovCiAgICAgICAgY2FzZSBDT01NRU5UOgogICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgxMDAwKSB7CiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvcHkgPSAwOwogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgbGVuID0gaW5wdXRbbmV4dCArIGNvcHkrK107CiAgICAgICAgICAgICAgLyogdXNlIGNvbnN0YW50IGxpbWl0IGJlY2F1c2UgaW4ganMgd2Ugc2hvdWxkIG5vdCBwcmVhbGxvY2F0ZSBtZW1vcnkgKi8KICAgICAgICAgICAgICBpZiAoc3RhdGUuaGVhZCAmJiBsZW4gJiYgc3RhdGUubGVuZ3RoIDwgNjU1MzYgLypzdGF0ZS5oZWFkLmNvbW1fbWF4Ki8pIHsKICAgICAgICAgICAgICAgIHN0YXRlLmhlYWQuY29tbWVudCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGxlbik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IHdoaWxlIChsZW4gJiYgY29weSA8IGhhdmUpOwogICAgICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHsKICAgICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBpbnB1dCwgY29weSwgbmV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaGF2ZSAtPSBjb3B5OwogICAgICAgICAgICBuZXh0ICs9IGNvcHk7CiAgICAgICAgICAgIGlmIChsZW4pIHsKICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUuaGVhZCkgewogICAgICAgICAgICBzdGF0ZS5oZWFkLmNvbW1lbnQgPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgc3RhdGUubW9kZSA9IEhDUkM7CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgSENSQzoKICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkgewogICAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovCiAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgMTYpIHsKICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgICAgaWYgKGhvbGQgIT09IChzdGF0ZS5jaGVjayAmIDB4ZmZmZikpIHsKICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdoZWFkZXIgY3JjIG1pc21hdGNoJzsKICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7CiAgICAgICAgICAgIGhvbGQgPSAwOwogICAgICAgICAgICBiaXRzID0gMDsKICAgICAgICAgICAgLy89PT0vLwogICAgICAgICAgfQogICAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHsKICAgICAgICAgICAgc3RhdGUuaGVhZC5oY3JjID0gc3RhdGUuZmxhZ3MgPj4gOSAmIDE7CiAgICAgICAgICAgIHN0YXRlLmhlYWQuZG9uZSA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAwOwogICAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIERJQ1RJRDoKICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi8KICAgICAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHsKICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsKICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaGF2ZS0tOwogICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0czsKICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgfQogICAgICAgICAgLy89PT0vLwogICAgICAgICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID0genN3YXAzMihob2xkKTsKICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7CiAgICAgICAgICBob2xkID0gMDsKICAgICAgICAgIGJpdHMgPSAwOwogICAgICAgICAgLy89PT0vLwogICAgICAgICAgc3RhdGUubW9kZSA9IERJQ1Q7CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgRElDVDoKICAgICAgICAgIGlmIChzdGF0ZS5oYXZlZGljdCA9PT0gMCkgewogICAgICAgICAgICAvLy0tLSBSRVNUT1JFKCkgLS0tCiAgICAgICAgICAgIHN0cm0ubmV4dF9vdXQgPSBwdXQ7CiAgICAgICAgICAgIHN0cm0uYXZhaWxfb3V0ID0gbGVmdDsKICAgICAgICAgICAgc3RybS5uZXh0X2luID0gbmV4dDsKICAgICAgICAgICAgc3RybS5hdmFpbF9pbiA9IGhhdmU7CiAgICAgICAgICAgIHN0YXRlLmhvbGQgPSBob2xkOwogICAgICAgICAgICBzdGF0ZS5iaXRzID0gYml0czsKICAgICAgICAgICAgLy8tLS0KICAgICAgICAgICAgcmV0dXJuIFpfTkVFRF9ESUNUJDE7CiAgICAgICAgICB9CiAgICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAxIC8qYWRsZXIzMigwTCwgWl9OVUxMLCAwKSovOwogICAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgVFlQRToKICAgICAgICAgIGlmIChmbHVzaCA9PT0gWl9CTE9DSyB8fCBmbHVzaCA9PT0gWl9UUkVFUykgewogICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICB9CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgVFlQRURPOgogICAgICAgICAgaWYgKHN0YXRlLmxhc3QpIHsKICAgICAgICAgICAgLy8tLS0gQllURUJJVFMoKSAtLS0vLwogICAgICAgICAgICBob2xkID4+Pj0gYml0cyAmIDc7CiAgICAgICAgICAgIGJpdHMgLT0gYml0cyAmIDc7CiAgICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgICAgc3RhdGUubW9kZSA9IENIRUNLOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMpOyAqLwogICAgICAgICAgd2hpbGUgKGJpdHMgPCAzKSB7CiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhhdmUtLTsKICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgIH0KICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgIHN0YXRlLmxhc3QgPSBob2xkICYgMHgwMSAvKkJJVFMoMSkqLzsKICAgICAgICAgIC8vLS0tIERST1BCSVRTKDEpIC0tLS8vCiAgICAgICAgICBob2xkID4+Pj0gMTsKICAgICAgICAgIGJpdHMgLT0gMTsKICAgICAgICAgIC8vLS0tLy8KCiAgICAgICAgICBzd2l0Y2ggKGhvbGQgJiAweDAzIC8qQklUUygyKSovKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAvKiBzdG9yZWQgYmxvY2sgKi8KICAgICAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCAiaW5mbGF0ZTogICAgIHN0b3JlZCBibG9jayVzXG4iLAogICAgICAgICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gIiAobGFzdCkiIDogIiIpKTsKICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gU1RPUkVEOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgLyogZml4ZWQgYmxvY2sgKi8KICAgICAgICAgICAgICBmaXhlZHRhYmxlcyhzdGF0ZSk7CiAgICAgICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgImluZmxhdGU6ICAgICBmaXhlZCBjb2RlcyBibG9jayVzXG4iLAogICAgICAgICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gIiAobGFzdCkiIDogIiIpKTsKICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gTEVOXzsgLyogZGVjb2RlIGNvZGVzICovCiAgICAgICAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7CiAgICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUygyKSAtLS0vLwogICAgICAgICAgICAgICAgaG9sZCA+Pj49IDI7CiAgICAgICAgICAgICAgICBiaXRzIC09IDI7CiAgICAgICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgLyogZHluYW1pYyBibG9jayAqLwogICAgICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsICJpbmZsYXRlOiAgICAgZHluYW1pYyBjb2RlcyBibG9jayVzXG4iLAogICAgICAgICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gIiAobGFzdCkiIDogIiIpKTsKICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gVEFCTEU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGJsb2NrIHR5cGUnOwogICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7CiAgICAgICAgICB9CiAgICAgICAgICAvLy0tLSBEUk9QQklUUygyKSAtLS0vLwogICAgICAgICAgaG9sZCA+Pj49IDI7CiAgICAgICAgICBiaXRzIC09IDI7CiAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFNUT1JFRDoKICAgICAgICAgIC8vLS0tIEJZVEVCSVRTKCkgLS0tLy8gLyogZ28gdG8gYnl0ZSBib3VuZGFyeSAqLwogICAgICAgICAgaG9sZCA+Pj49IGJpdHMgJiA3OwogICAgICAgICAgYml0cyAtPSBiaXRzICYgNzsKICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi8KICAgICAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHsKICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsKICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaGF2ZS0tOwogICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0czsKICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgfQogICAgICAgICAgLy89PT0vLwogICAgICAgICAgaWYgKChob2xkICYgMHhmZmZmKSAhPT0gKGhvbGQgPj4+IDE2IF4gMHhmZmZmKSkgewogICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIHN0b3JlZCBibG9jayBsZW5ndGhzJzsKICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBzdGF0ZS5sZW5ndGggPSBob2xkICYgMHhmZmZmOwogICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgImluZmxhdGU6ICAgICAgIHN0b3JlZCBsZW5ndGggJXVcbiIsCiAgICAgICAgICAvLyAgICAgICAgc3RhdGUubGVuZ3RoKSk7CiAgICAgICAgICAvLz09PSBJTklUQklUUygpOwogICAgICAgICAgaG9sZCA9IDA7CiAgICAgICAgICBiaXRzID0gMDsKICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgIHN0YXRlLm1vZGUgPSBDT1BZXzsKICAgICAgICAgIGlmIChmbHVzaCA9PT0gWl9UUkVFUykgewogICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICB9CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgQ09QWV86CiAgICAgICAgICBzdGF0ZS5tb2RlID0gQ09QWTsKICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovCiAgICAgICAgY2FzZSBDT1BZOgogICAgICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDsKICAgICAgICAgIGlmIChjb3B5KSB7CiAgICAgICAgICAgIGlmIChjb3B5ID4gaGF2ZSkgewogICAgICAgICAgICAgIGNvcHkgPSBoYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb3B5ID4gbGVmdCkgewogICAgICAgICAgICAgIGNvcHkgPSBsZWZ0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb3B5ID09PSAwKSB7CiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vLS0tIHptZW1jcHkocHV0LCBuZXh0LCBjb3B5KTsgLS0tCiAgICAgICAgICAgIG91dHB1dC5zZXQoaW5wdXQuc3ViYXJyYXkobmV4dCwgbmV4dCArIGNvcHkpLCBwdXQpOwogICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgIGhhdmUgLT0gY29weTsKICAgICAgICAgICAgbmV4dCArPSBjb3B5OwogICAgICAgICAgICBsZWZ0IC09IGNvcHk7CiAgICAgICAgICAgIHB1dCArPSBjb3B5OwogICAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCAiaW5mbGF0ZTogICAgICAgc3RvcmVkIGVuZFxuIikpOwogICAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRBQkxFOgogICAgICAgICAgLy89PT0gTkVFREJJVFMoMTQpOyAqLwogICAgICAgICAgd2hpbGUgKGJpdHMgPCAxNCkgewogICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICBiaXRzICs9IDg7CiAgICAgICAgICB9CiAgICAgICAgICAvLz09PS8vCiAgICAgICAgICBzdGF0ZS5ubGVuID0gKGhvbGQgJiAweDFmIC8qQklUUyg1KSovKSArIDI1NzsKICAgICAgICAgIC8vLS0tIERST1BCSVRTKDUpIC0tLS8vCiAgICAgICAgICBob2xkID4+Pj0gNTsKICAgICAgICAgIGJpdHMgLT0gNTsKICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgIHN0YXRlLm5kaXN0ID0gKGhvbGQgJiAweDFmIC8qQklUUyg1KSovKSArIDE7CiAgICAgICAgICAvLy0tLSBEUk9QQklUUyg1KSAtLS0vLwogICAgICAgICAgaG9sZCA+Pj49IDU7CiAgICAgICAgICBiaXRzIC09IDU7CiAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICBzdGF0ZS5uY29kZSA9IChob2xkICYgMHgwZiAvKkJJVFMoNCkqLykgKyA0OwogICAgICAgICAgLy8tLS0gRFJPUEJJVFMoNCkgLS0tLy8KICAgICAgICAgIGhvbGQgPj4+PSA0OwogICAgICAgICAgYml0cyAtPSA0OwogICAgICAgICAgLy8tLS0vLwogICAgICAgICAgLy8jaWZuZGVmIFBLWklQX0JVR19XT1JLQVJPVU5ECiAgICAgICAgICBpZiAoc3RhdGUubmxlbiA+IDI4NiB8fCBzdGF0ZS5uZGlzdCA+IDMwKSB7CiAgICAgICAgICAgIHN0cm0ubXNnID0gJ3RvbyBtYW55IGxlbmd0aCBvciBkaXN0YW5jZSBzeW1ib2xzJzsKICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICAvLyNlbmRpZgogICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgImluZmxhdGU6ICAgICAgIHRhYmxlIHNpemVzIG9rXG4iKSk7CiAgICAgICAgICBzdGF0ZS5oYXZlID0gMDsKICAgICAgICAgIHN0YXRlLm1vZGUgPSBMRU5MRU5TOwogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlIExFTkxFTlM6CiAgICAgICAgICB3aGlsZSAoc3RhdGUuaGF2ZSA8IHN0YXRlLm5jb2RlKSB7CiAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMpOwogICAgICAgICAgICB3aGlsZSAoYml0cyA8IDMpIHsKICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgICAgc3RhdGUubGVuc1tvcmRlcltzdGF0ZS5oYXZlKytdXSA9IGhvbGQgJiAweDA3OyAvL0JJVFMoMyk7CiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDMpIC0tLS8vCiAgICAgICAgICAgIGhvbGQgPj4+PSAzOwogICAgICAgICAgICBiaXRzIC09IDM7CiAgICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgIH0KICAgICAgICAgIHdoaWxlIChzdGF0ZS5oYXZlIDwgMTkpIHsKICAgICAgICAgICAgc3RhdGUubGVuc1tvcmRlcltzdGF0ZS5oYXZlKytdXSA9IDA7CiAgICAgICAgICB9CiAgICAgICAgICAvLyBXZSBoYXZlIHNlcGFyYXRlIHRhYmxlcyAmIG5vIHBvaW50ZXJzLiAyIGNvbW1lbnRlZCBsaW5lcyBiZWxvdyBub3QgbmVlZGVkLgogICAgICAgICAgLy9zdGF0ZS5uZXh0ID0gc3RhdGUuY29kZXM7CiAgICAgICAgICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0OwogICAgICAgICAgLy8gU3dpdGNoIHRvIHVzZSBkeW5hbWljIHRhYmxlCiAgICAgICAgICBzdGF0ZS5sZW5jb2RlID0gc3RhdGUubGVuZHluOwogICAgICAgICAgc3RhdGUubGVuYml0cyA9IDc7CiAgICAgICAgICBvcHRzID0gewogICAgICAgICAgICBiaXRzOiBzdGF0ZS5sZW5iaXRzCiAgICAgICAgICB9OwogICAgICAgICAgcmV0ID0gaW5mbGF0ZV90YWJsZShDT0RFUywgc3RhdGUubGVucywgMCwgMTksIHN0YXRlLmxlbmNvZGUsIDAsIHN0YXRlLndvcmssIG9wdHMpOwogICAgICAgICAgc3RhdGUubGVuYml0cyA9IG9wdHMuYml0czsKICAgICAgICAgIGlmIChyZXQpIHsKICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBjb2RlIGxlbmd0aHMgc2V0JzsKICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCAiaW5mbGF0ZTogICAgICAgY29kZSBsZW5ndGhzIG9rXG4iKSk7CiAgICAgICAgICBzdGF0ZS5oYXZlID0gMDsKICAgICAgICAgIHN0YXRlLm1vZGUgPSBDT0RFTEVOUzsKICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovCiAgICAgICAgY2FzZSBDT0RFTEVOUzoKICAgICAgICAgIHdoaWxlIChzdGF0ZS5oYXZlIDwgc3RhdGUubmxlbiArIHN0YXRlLm5kaXN0KSB7CiAgICAgICAgICAgIGZvciAoOzspIHsKICAgICAgICAgICAgICBoZXJlID0gc3RhdGUubGVuY29kZVtob2xkICYgKDEgPDwgc3RhdGUubGVuYml0cykgLSAxXTsgLypCSVRTKHN0YXRlLmxlbmJpdHMpKi8KICAgICAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDsKICAgICAgICAgICAgICBoZXJlX29wID0gaGVyZSA+Pj4gMTYgJiAweGZmOwogICAgICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjsKICAgICAgICAgICAgICBpZiAoaGVyZV9iaXRzIDw9IGJpdHMpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vCiAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsKICAgICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaGF2ZS0tOwogICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGhlcmVfdmFsIDwgMTYpIHsKICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vCiAgICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0czsKICAgICAgICAgICAgICBiaXRzIC09IGhlcmVfYml0czsKICAgICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgICAgc3RhdGUubGVuc1tzdGF0ZS5oYXZlKytdID0gaGVyZV92YWw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgaWYgKGhlcmVfdmFsID09PSAxNikgewogICAgICAgICAgICAgICAgLy89PT0gTkVFREJJVFMoaGVyZS5iaXRzICsgMik7CiAgICAgICAgICAgICAgICBuID0gaGVyZV9iaXRzICsgMjsKICAgICAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikgewogICAgICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICAgICAgICBiaXRzICs9IDg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLz09PS8vCiAgICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vCiAgICAgICAgICAgICAgICBob2xkID4+Pj0gaGVyZV9iaXRzOwogICAgICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7CiAgICAgICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgICAgICBpZiAoc3RhdGUuaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGJpdCBsZW5ndGggcmVwZWF0JzsKICAgICAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsZW4gPSBzdGF0ZS5sZW5zW3N0YXRlLmhhdmUgLSAxXTsKICAgICAgICAgICAgICAgIGNvcHkgPSAzICsgKGhvbGQgJiAweDAzKTsgLy9CSVRTKDIpOwogICAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy8KICAgICAgICAgICAgICAgIGhvbGQgPj4+PSAyOwogICAgICAgICAgICAgICAgYml0cyAtPSAyOwogICAgICAgICAgICAgICAgLy8tLS0vLwogICAgICAgICAgICAgIH0gZWxzZSBpZiAoaGVyZV92YWwgPT09IDE3KSB7CiAgICAgICAgICAgICAgICAvLz09PSBORUVEQklUUyhoZXJlLmJpdHMgKyAzKTsKICAgICAgICAgICAgICAgIG4gPSBoZXJlX2JpdHMgKyAzOwogICAgICAgICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7CiAgICAgICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGhhdmUtLTsKICAgICAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy8KICAgICAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7CiAgICAgICAgICAgICAgICBiaXRzIC09IGhlcmVfYml0czsKICAgICAgICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgICAgICAgIGxlbiA9IDA7CiAgICAgICAgICAgICAgICBjb3B5ID0gMyArIChob2xkICYgMHgwNyk7IC8vQklUUygzKTsKICAgICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDMpIC0tLS8vCiAgICAgICAgICAgICAgICBob2xkID4+Pj0gMzsKICAgICAgICAgICAgICAgIGJpdHMgLT0gMzsKICAgICAgICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy89PT0gTkVFREJJVFMoaGVyZS5iaXRzICsgNyk7CiAgICAgICAgICAgICAgICBuID0gaGVyZV9iaXRzICsgNzsKICAgICAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikgewogICAgICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICAgICAgICBiaXRzICs9IDg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLz09PS8vCiAgICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vCiAgICAgICAgICAgICAgICBob2xkID4+Pj0gaGVyZV9iaXRzOwogICAgICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7CiAgICAgICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgICAgICBsZW4gPSAwOwogICAgICAgICAgICAgICAgY29weSA9IDExICsgKGhvbGQgJiAweDdmKTsgLy9CSVRTKDcpOwogICAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoNykgLS0tLy8KICAgICAgICAgICAgICAgIGhvbGQgPj4+PSA3OwogICAgICAgICAgICAgICAgYml0cyAtPSA3OwogICAgICAgICAgICAgICAgLy8tLS0vLwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoc3RhdGUuaGF2ZSArIGNvcHkgPiBzdGF0ZS5ubGVuICsgc3RhdGUubmRpc3QpIHsKICAgICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgYml0IGxlbmd0aCByZXBlYXQnOwogICAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB3aGlsZSAoY29weS0tKSB7CiAgICAgICAgICAgICAgICBzdGF0ZS5sZW5zW3N0YXRlLmhhdmUrK10gPSBsZW47CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgLyogaGFuZGxlIGVycm9yIGJyZWFrcyBpbiB3aGlsZSAqLwogICAgICAgICAgaWYgKHN0YXRlLm1vZGUgPT09IEJBRCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBjaGVjayBmb3IgZW5kLW9mLWJsb2NrIGNvZGUgKGJldHRlciBoYXZlIG9uZSkgKi8KICAgICAgICAgIGlmIChzdGF0ZS5sZW5zWzI1Nl0gPT09IDApIHsKICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrJzsKICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CgogICAgICAgICAgLyogYnVpbGQgY29kZSB0YWJsZXMgLS0gbm90ZTogZG8gbm90IGNoYW5nZSB0aGUgbGVuYml0cyBvciBkaXN0Yml0cwogICAgICAgICAgICAgdmFsdWVzIGhlcmUgKDkgYW5kIDYpIHdpdGhvdXQgcmVhZGluZyB0aGUgY29tbWVudHMgaW4gaW5mdHJlZXMuaAogICAgICAgICAgICAgY29uY2VybmluZyB0aGUgRU5PVUdIIGNvbnN0YW50cywgd2hpY2ggZGVwZW5kIG9uIHRob3NlIHZhbHVlcyAqLwogICAgICAgICAgc3RhdGUubGVuYml0cyA9IDk7CiAgICAgICAgICBvcHRzID0gewogICAgICAgICAgICBiaXRzOiBzdGF0ZS5sZW5iaXRzCiAgICAgICAgICB9OwogICAgICAgICAgcmV0ID0gaW5mbGF0ZV90YWJsZShMRU5TLCBzdGF0ZS5sZW5zLCAwLCBzdGF0ZS5ubGVuLCBzdGF0ZS5sZW5jb2RlLCAwLCBzdGF0ZS53b3JrLCBvcHRzKTsKICAgICAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuCiAgICAgICAgICAvLyBzdGF0ZS5uZXh0X2luZGV4ID0gb3B0cy50YWJsZV9pbmRleDsKICAgICAgICAgIHN0YXRlLmxlbmJpdHMgPSBvcHRzLmJpdHM7CiAgICAgICAgICAvLyBzdGF0ZS5sZW5jb2RlID0gc3RhdGUubmV4dDsKCiAgICAgICAgICBpZiAocmV0KSB7CiAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGhzIHNldCc7CiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgc3RhdGUuZGlzdGJpdHMgPSA2OwogICAgICAgICAgLy9zdGF0ZS5kaXN0Y29kZS5jb3B5KHN0YXRlLmNvZGVzKTsKICAgICAgICAgIC8vIFN3aXRjaCB0byB1c2UgZHluYW1pYyB0YWJsZQogICAgICAgICAgc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5kaXN0ZHluOwogICAgICAgICAgb3B0cyA9IHsKICAgICAgICAgICAgYml0czogc3RhdGUuZGlzdGJpdHMKICAgICAgICAgIH07CiAgICAgICAgICByZXQgPSBpbmZsYXRlX3RhYmxlKERJU1RTLCBzdGF0ZS5sZW5zLCBzdGF0ZS5ubGVuLCBzdGF0ZS5uZGlzdCwgc3RhdGUuZGlzdGNvZGUsIDAsIHN0YXRlLndvcmssIG9wdHMpOwogICAgICAgICAgLy8gV2UgaGF2ZSBzZXBhcmF0ZSB0YWJsZXMgJiBubyBwb2ludGVycy4gMiBjb21tZW50ZWQgbGluZXMgYmVsb3cgbm90IG5lZWRlZC4KICAgICAgICAgIC8vIHN0YXRlLm5leHRfaW5kZXggPSBvcHRzLnRhYmxlX2luZGV4OwogICAgICAgICAgc3RhdGUuZGlzdGJpdHMgPSBvcHRzLmJpdHM7CiAgICAgICAgICAvLyBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLm5leHQ7CgogICAgICAgICAgaWYgKHJldCkgewogICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlcyBzZXQnOwogICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsICdpbmZsYXRlOiAgICAgICBjb2RlcyBva1xuJykpOwogICAgICAgICAgc3RhdGUubW9kZSA9IExFTl87CiAgICAgICAgICBpZiAoZmx1c2ggPT09IFpfVFJFRVMpIHsKICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgfQogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlIExFTl86CiAgICAgICAgICBzdGF0ZS5tb2RlID0gTEVOOwogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlIExFTjoKICAgICAgICAgIGlmIChoYXZlID49IDYgJiYgbGVmdCA+PSAyNTgpIHsKICAgICAgICAgICAgLy8tLS0gUkVTVE9SRSgpIC0tLQogICAgICAgICAgICBzdHJtLm5leHRfb3V0ID0gcHV0OwogICAgICAgICAgICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7CiAgICAgICAgICAgIHN0cm0ubmV4dF9pbiA9IG5leHQ7CiAgICAgICAgICAgIHN0cm0uYXZhaWxfaW4gPSBoYXZlOwogICAgICAgICAgICBzdGF0ZS5ob2xkID0gaG9sZDsKICAgICAgICAgICAgc3RhdGUuYml0cyA9IGJpdHM7CiAgICAgICAgICAgIC8vLS0tCiAgICAgICAgICAgIGluZmxhdGVfZmFzdChzdHJtLCBfb3V0KTsKICAgICAgICAgICAgLy8tLS0gTE9BRCgpIC0tLQogICAgICAgICAgICBwdXQgPSBzdHJtLm5leHRfb3V0OwogICAgICAgICAgICBvdXRwdXQgPSBzdHJtLm91dHB1dDsKICAgICAgICAgICAgbGVmdCA9IHN0cm0uYXZhaWxfb3V0OwogICAgICAgICAgICBuZXh0ID0gc3RybS5uZXh0X2luOwogICAgICAgICAgICBpbnB1dCA9IHN0cm0uaW5wdXQ7CiAgICAgICAgICAgIGhhdmUgPSBzdHJtLmF2YWlsX2luOwogICAgICAgICAgICBob2xkID0gc3RhdGUuaG9sZDsKICAgICAgICAgICAgYml0cyA9IHN0YXRlLmJpdHM7CiAgICAgICAgICAgIC8vLS0tCgogICAgICAgICAgICBpZiAoc3RhdGUubW9kZSA9PT0gVFlQRSkgewogICAgICAgICAgICAgIHN0YXRlLmJhY2sgPSAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIHN0YXRlLmJhY2sgPSAwOwogICAgICAgICAgZm9yICg7OykgewogICAgICAgICAgICBoZXJlID0gc3RhdGUubGVuY29kZVtob2xkICYgKDEgPDwgc3RhdGUubGVuYml0cykgLSAxXTsgLypCSVRTKHN0YXRlLmxlbmJpdHMpKi8KICAgICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7CiAgICAgICAgICAgIGhlcmVfb3AgPSBoZXJlID4+PiAxNiAmIDB4ZmY7CiAgICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjsKICAgICAgICAgICAgaWYgKGhlcmVfYml0cyA8PSBiaXRzKSB7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vLwogICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICBiaXRzICs9IDg7CiAgICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgIH0KICAgICAgICAgIGlmIChoZXJlX29wICYmIChoZXJlX29wICYgMHhmMCkgPT09IDApIHsKICAgICAgICAgICAgbGFzdF9iaXRzID0gaGVyZV9iaXRzOwogICAgICAgICAgICBsYXN0X29wID0gaGVyZV9vcDsKICAgICAgICAgICAgbGFzdF92YWwgPSBoZXJlX3ZhbDsKICAgICAgICAgICAgZm9yICg7OykgewogICAgICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2xhc3RfdmFsICsgKChob2xkICYgKDEgPDwgbGFzdF9iaXRzICsgbGFzdF9vcCkgLSAxIC8qQklUUyhsYXN0LmJpdHMgKyBsYXN0Lm9wKSovKSA+PiBsYXN0X2JpdHMpXTsKICAgICAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDsKICAgICAgICAgICAgICBoZXJlX29wID0gaGVyZSA+Pj4gMTYgJiAweGZmOwogICAgICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjsKICAgICAgICAgICAgICBpZiAobGFzdF9iaXRzICsgaGVyZV9iaXRzIDw9IGJpdHMpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vCiAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsKICAgICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaGF2ZS0tOwogICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMobGFzdC5iaXRzKSAtLS0vLwogICAgICAgICAgICBob2xkID4+Pj0gbGFzdF9iaXRzOwogICAgICAgICAgICBiaXRzIC09IGxhc3RfYml0czsKICAgICAgICAgICAgLy8tLS0vLwogICAgICAgICAgICBzdGF0ZS5iYWNrICs9IGxhc3RfYml0czsKICAgICAgICAgIH0KICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy8KICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7CiAgICAgICAgICBiaXRzIC09IGhlcmVfYml0czsKICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgIHN0YXRlLmJhY2sgKz0gaGVyZV9iaXRzOwogICAgICAgICAgc3RhdGUubGVuZ3RoID0gaGVyZV92YWw7CiAgICAgICAgICBpZiAoaGVyZV9vcCA9PT0gMCkgewogICAgICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgaGVyZS52YWwgPj0gMHgyMCAmJiBoZXJlLnZhbCA8IDB4N2YgPwogICAgICAgICAgICAvLyAgICAgICAgImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAnJWMnXG4iIDoKICAgICAgICAgICAgLy8gICAgICAgICJpbmZsYXRlOiAgICAgICAgIGxpdGVyYWwgMHglMDJ4XG4iLCBoZXJlLnZhbCkpOwogICAgICAgICAgICBzdGF0ZS5tb2RlID0gTElUOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChoZXJlX29wICYgMzIpIHsKICAgICAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsICJpbmZsYXRlOiAgICAgICAgIGVuZCBvZiBibG9ja1xuIikpOwogICAgICAgICAgICBzdGF0ZS5iYWNrID0gLTE7CiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChoZXJlX29wICYgNjQpIHsKICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBsaXRlcmFsL2xlbmd0aCBjb2RlJzsKICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBzdGF0ZS5leHRyYSA9IGhlcmVfb3AgJiAxNTsKICAgICAgICAgIHN0YXRlLm1vZGUgPSBMRU5FWFQ7CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgTEVORVhUOgogICAgICAgICAgaWYgKHN0YXRlLmV4dHJhKSB7CiAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKHN0YXRlLmV4dHJhKTsKICAgICAgICAgICAgbiA9IHN0YXRlLmV4dHJhOwogICAgICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHsKICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgICAgc3RhdGUubGVuZ3RoICs9IGhvbGQgJiAoMSA8PCBzdGF0ZS5leHRyYSkgLSAxIC8qQklUUyhzdGF0ZS5leHRyYSkqLzsKICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoc3RhdGUuZXh0cmEpIC0tLS8vCiAgICAgICAgICAgIGhvbGQgPj4+PSBzdGF0ZS5leHRyYTsKICAgICAgICAgICAgYml0cyAtPSBzdGF0ZS5leHRyYTsKICAgICAgICAgICAgLy8tLS0vLwogICAgICAgICAgICBzdGF0ZS5iYWNrICs9IHN0YXRlLmV4dHJhOwogICAgICAgICAgfQogICAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsICJpbmZsYXRlOiAgICAgICAgIGxlbmd0aCAldVxuIiwgc3RhdGUubGVuZ3RoKSk7CiAgICAgICAgICBzdGF0ZS53YXMgPSBzdGF0ZS5sZW5ndGg7CiAgICAgICAgICBzdGF0ZS5tb2RlID0gRElTVDsKICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovCiAgICAgICAgY2FzZSBESVNUOgogICAgICAgICAgZm9yICg7OykgewogICAgICAgICAgICBoZXJlID0gc3RhdGUuZGlzdGNvZGVbaG9sZCAmICgxIDw8IHN0YXRlLmRpc3RiaXRzKSAtIDFdOyAvKkJJVFMoc3RhdGUuZGlzdGJpdHMpKi8KICAgICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7CiAgICAgICAgICAgIGhlcmVfb3AgPSBoZXJlID4+PiAxNiAmIDB4ZmY7CiAgICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjsKICAgICAgICAgICAgaWYgKGhlcmVfYml0cyA8PSBiaXRzKSB7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vLwogICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICBiaXRzICs9IDg7CiAgICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgIH0KICAgICAgICAgIGlmICgoaGVyZV9vcCAmIDB4ZjApID09PSAwKSB7CiAgICAgICAgICAgIGxhc3RfYml0cyA9IGhlcmVfYml0czsKICAgICAgICAgICAgbGFzdF9vcCA9IGhlcmVfb3A7CiAgICAgICAgICAgIGxhc3RfdmFsID0gaGVyZV92YWw7CiAgICAgICAgICAgIGZvciAoOzspIHsKICAgICAgICAgICAgICBoZXJlID0gc3RhdGUuZGlzdGNvZGVbbGFzdF92YWwgKyAoKGhvbGQgJiAoMSA8PCBsYXN0X2JpdHMgKyBsYXN0X29wKSAtIDEgLypCSVRTKGxhc3QuYml0cyArIGxhc3Qub3ApKi8pID4+IGxhc3RfYml0cyldOwogICAgICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0OwogICAgICAgICAgICAgIGhlcmVfb3AgPSBoZXJlID4+PiAxNiAmIDB4ZmY7CiAgICAgICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmOwogICAgICAgICAgICAgIGlmIChsYXN0X2JpdHMgKyBoZXJlX2JpdHMgPD0gYml0cykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8vLS0tIFBVTExCWVRFKCkgLS0tLy8KICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgICAgIC8vLS0tLy8KICAgICAgICAgICAgfQogICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhsYXN0LmJpdHMpIC0tLS8vCiAgICAgICAgICAgIGhvbGQgPj4+PSBsYXN0X2JpdHM7CiAgICAgICAgICAgIGJpdHMgLT0gbGFzdF9iaXRzOwogICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgIHN0YXRlLmJhY2sgKz0gbGFzdF9iaXRzOwogICAgICAgICAgfQogICAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vLwogICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0czsKICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzOwogICAgICAgICAgLy8tLS0vLwogICAgICAgICAgc3RhdGUuYmFjayArPSBoZXJlX2JpdHM7CiAgICAgICAgICBpZiAoaGVyZV9vcCAmIDY0KSB7CiAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgY29kZSc7CiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgc3RhdGUub2Zmc2V0ID0gaGVyZV92YWw7CiAgICAgICAgICBzdGF0ZS5leHRyYSA9IGhlcmVfb3AgJiAxNTsKICAgICAgICAgIHN0YXRlLm1vZGUgPSBESVNURVhUOwogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlIERJU1RFWFQ6CiAgICAgICAgICBpZiAoc3RhdGUuZXh0cmEpIHsKICAgICAgICAgICAgLy89PT0gTkVFREJJVFMoc3RhdGUuZXh0cmEpOwogICAgICAgICAgICBuID0gc3RhdGUuZXh0cmE7CiAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikgewogICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7CiAgICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGhhdmUtLTsKICAgICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0czsKICAgICAgICAgICAgICBiaXRzICs9IDg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy89PT0vLwogICAgICAgICAgICBzdGF0ZS5vZmZzZXQgKz0gaG9sZCAmICgxIDw8IHN0YXRlLmV4dHJhKSAtIDEgLypCSVRTKHN0YXRlLmV4dHJhKSovOwogICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhzdGF0ZS5leHRyYSkgLS0tLy8KICAgICAgICAgICAgaG9sZCA+Pj49IHN0YXRlLmV4dHJhOwogICAgICAgICAgICBiaXRzIC09IHN0YXRlLmV4dHJhOwogICAgICAgICAgICAvLy0tLS8vCiAgICAgICAgICAgIHN0YXRlLmJhY2sgKz0gc3RhdGUuZXh0cmE7CiAgICAgICAgICB9CiAgICAgICAgICAvLyNpZmRlZiBJTkZMQVRFX1NUUklDVAogICAgICAgICAgaWYgKHN0YXRlLm9mZnNldCA+IHN0YXRlLmRtYXgpIHsKICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snOwogICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIC8vI2VuZGlmCiAgICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgImluZmxhdGU6ICAgICAgICAgZGlzdGFuY2UgJXVcbiIsIHN0YXRlLm9mZnNldCkpOwogICAgICAgICAgc3RhdGUubW9kZSA9IE1BVENIOwogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlIE1BVENIOgogICAgICAgICAgaWYgKGxlZnQgPT09IDApIHsKICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgfQogICAgICAgICAgY29weSA9IF9vdXQgLSBsZWZ0OwogICAgICAgICAgaWYgKHN0YXRlLm9mZnNldCA+IGNvcHkpIHsKICAgICAgICAgICAgLyogY29weSBmcm9tIHdpbmRvdyAqLwogICAgICAgICAgICBjb3B5ID0gc3RhdGUub2Zmc2V0IC0gY29weTsKICAgICAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS53aGF2ZSkgewogICAgICAgICAgICAgIGlmIChzdGF0ZS5zYW5lKSB7CiAgICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7CiAgICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8vICghKSBUaGlzIGJsb2NrIGlzIGRpc2FibGVkIGluIHpsaWIgZGVmYXVsdHMsCiAgICAgICAgICAgICAgLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eQogICAgICAgICAgICAgIC8vI2lmZGVmIElORkxBVEVfQUxMT1dfSU5WQUxJRF9ESVNUQU5DRV9UT09GQVJfQVJSUgogICAgICAgICAgICAgIC8vICAgICAgICAgIFRyYWNlKChzdGRlcnIsICJpbmZsYXRlLmMgdG9vIGZhclxuIikpOwogICAgICAgICAgICAgIC8vICAgICAgICAgIGNvcHkgLT0gc3RhdGUud2hhdmU7CiAgICAgICAgICAgICAgLy8gICAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS5sZW5ndGgpIHsgY29weSA9IHN0YXRlLmxlbmd0aDsgfQogICAgICAgICAgICAgIC8vICAgICAgICAgIGlmIChjb3B5ID4gbGVmdCkgeyBjb3B5ID0gbGVmdDsgfQogICAgICAgICAgICAgIC8vICAgICAgICAgIGxlZnQgLT0gY29weTsKICAgICAgICAgICAgICAvLyAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTsKICAgICAgICAgICAgICAvLyAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgLy8gICAgICAgICAgICBvdXRwdXRbcHV0KytdID0gMDsKICAgICAgICAgICAgICAvLyAgICAgICAgICB9IHdoaWxlICgtLWNvcHkpOwogICAgICAgICAgICAgIC8vICAgICAgICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHsgc3RhdGUubW9kZSA9IExFTjsgfQogICAgICAgICAgICAgIC8vICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIC8vI2VuZGlmCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS53bmV4dCkgewogICAgICAgICAgICAgIGNvcHkgLT0gc3RhdGUud25leHQ7CiAgICAgICAgICAgICAgZnJvbSA9IHN0YXRlLndzaXplIC0gY29weTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmcm9tID0gc3RhdGUud25leHQgLSBjb3B5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb3B5ID4gc3RhdGUubGVuZ3RoKSB7CiAgICAgICAgICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgICAgICBmcm9tX3NvdXJjZSA9IHN0YXRlLndpbmRvdzsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIGNvcHkgZnJvbSBvdXRwdXQgKi8KICAgICAgICAgICAgZnJvbV9zb3VyY2UgPSBvdXRwdXQ7CiAgICAgICAgICAgIGZyb20gPSBwdXQgLSBzdGF0ZS5vZmZzZXQ7CiAgICAgICAgICAgIGNvcHkgPSBzdGF0ZS5sZW5ndGg7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoY29weSA+IGxlZnQpIHsKICAgICAgICAgICAgY29weSA9IGxlZnQ7CiAgICAgICAgICB9CiAgICAgICAgICBsZWZ0IC09IGNvcHk7CiAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTsKICAgICAgICAgIGRvIHsKICAgICAgICAgICAgb3V0cHV0W3B1dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107CiAgICAgICAgICB9IHdoaWxlICgtLWNvcHkpOwogICAgICAgICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgewogICAgICAgICAgICBzdGF0ZS5tb2RlID0gTEVOOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBMSVQ6CiAgICAgICAgICBpZiAobGVmdCA9PT0gMCkgewogICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7CiAgICAgICAgICB9CiAgICAgICAgICBvdXRwdXRbcHV0KytdID0gc3RhdGUubGVuZ3RoOwogICAgICAgICAgbGVmdC0tOwogICAgICAgICAgc3RhdGUubW9kZSA9IExFTjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQ0hFQ0s6CiAgICAgICAgICBpZiAoc3RhdGUud3JhcCkgewogICAgICAgICAgICAvLz09PSBORUVEQklUUygzMik7CiAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHsKICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgewogICAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBoYXZlLS07CiAgICAgICAgICAgICAgLy8gVXNlICd8JyBpbnN0ZWFkIG9mICcrJyB0byBtYWtlIHN1cmUgdGhhdCByZXN1bHQgaXMgc2lnbmVkCiAgICAgICAgICAgICAgaG9sZCB8PSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7CiAgICAgICAgICAgICAgYml0cyArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vPT09Ly8KICAgICAgICAgICAgX291dCAtPSBsZWZ0OwogICAgICAgICAgICBzdHJtLnRvdGFsX291dCArPSBfb3V0OwogICAgICAgICAgICBzdGF0ZS50b3RhbCArPSBfb3V0OwogICAgICAgICAgICBpZiAoX291dCkgewogICAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IC8qVVBEQVRFKHN0YXRlLmNoZWNrLCBwdXQgLSBfb3V0LCBfb3V0KTsqLwogICAgICAgICAgICAgIHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgcHV0IC0gX291dCkgOiBhZGxlcjMyKHN0YXRlLmNoZWNrLCBvdXRwdXQsIF9vdXQsIHB1dCAtIF9vdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF9vdXQgPSBsZWZ0OwogICAgICAgICAgICAvLyBOQjogY3JjMzIgc3RvcmVkIGFzIHNpZ25lZCAzMi1iaXQgaW50LCB6c3dhcDMyIHJldHVybnMgc2lnbmVkIHRvbwogICAgICAgICAgICBpZiAoKHN0YXRlLmZsYWdzID8gaG9sZCA6IHpzd2FwMzIoaG9sZCkpICE9PSBzdGF0ZS5jaGVjaykgewogICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2luY29ycmVjdCBkYXRhIGNoZWNrJzsKICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7CiAgICAgICAgICAgIGhvbGQgPSAwOwogICAgICAgICAgICBiaXRzID0gMDsKICAgICAgICAgICAgLy89PT0vLwogICAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCAiaW5mbGF0ZTogICBjaGVjayBtYXRjaGVzIHRyYWlsZXJcbiIpKTsKICAgICAgICAgIH0KICAgICAgICAgIHN0YXRlLm1vZGUgPSBMRU5HVEg7CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgTEVOR1RIOgogICAgICAgICAgaWYgKHN0YXRlLndyYXAgJiYgc3RhdGUuZmxhZ3MpIHsKICAgICAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpOwogICAgICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7CiAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsKICAgICAgICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaGF2ZS0tOwogICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzOwogICAgICAgICAgICAgIGJpdHMgKz0gODsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLz09PS8vCiAgICAgICAgICAgIGlmIChob2xkICE9PSAoc3RhdGUudG90YWwgJiAweGZmZmZmZmZmKSkgewogICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2luY29ycmVjdCBsZW5ndGggY2hlY2snOwogICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTsKICAgICAgICAgICAgaG9sZCA9IDA7CiAgICAgICAgICAgIGJpdHMgPSAwOwogICAgICAgICAgICAvLz09PS8vCiAgICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsICJpbmZsYXRlOiAgIGxlbmd0aCBtYXRjaGVzIHRyYWlsZXJcbiIpKTsKICAgICAgICAgIH0KICAgICAgICAgIHN0YXRlLm1vZGUgPSBET05FOwogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBjYXNlIERPTkU6CiAgICAgICAgICByZXQgPSBaX1NUUkVBTV9FTkQkMTsKICAgICAgICAgIGJyZWFrIGluZl9sZWF2ZTsKICAgICAgICBjYXNlIEJBRDoKICAgICAgICAgIHJldCA9IFpfREFUQV9FUlJPUiQxOwogICAgICAgICAgYnJlYWsgaW5mX2xlYXZlOwogICAgICAgIGNhc2UgTUVNOgogICAgICAgICAgcmV0dXJuIFpfTUVNX0VSUk9SJDE7CiAgICAgICAgY2FzZSBTWU5DOgogICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi8KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7CiAgICAgIH0KICAgIH0KCiAgICAvLyBpbmZfbGVhdmUgPC0gaGVyZSBpcyByZWFsIHBsYWNlIGZvciAiZ290byBpbmZfbGVhdmUiLCBlbXVsYXRlZCB2aWEgImJyZWFrIGluZl9sZWF2ZSIKCiAgICAvKgogICAgICAgUmV0dXJuIGZyb20gaW5mbGF0ZSgpLCB1cGRhdGluZyB0aGUgdG90YWwgY291bnRzIGFuZCB0aGUgY2hlY2sgdmFsdWUuCiAgICAgICBJZiB0aGVyZSB3YXMgbm8gcHJvZ3Jlc3MgZHVyaW5nIHRoZSBpbmZsYXRlKCkgY2FsbCwgcmV0dXJuIGEgYnVmZmVyCiAgICAgICBlcnJvci4gIENhbGwgdXBkYXRld2luZG93KCkgdG8gY3JlYXRlIGFuZC9vciB1cGRhdGUgdGhlIHdpbmRvdyBzdGF0ZS4KICAgICAgIE5vdGU6IGEgbWVtb3J5IGVycm9yIGZyb20gaW5mbGF0ZSgpIGlzIG5vbi1yZWNvdmVyYWJsZS4KICAgICAqLwoKICAgIC8vLS0tIFJFU1RPUkUoKSAtLS0KICAgIHN0cm0ubmV4dF9vdXQgPSBwdXQ7CiAgICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7CiAgICBzdHJtLm5leHRfaW4gPSBuZXh0OwogICAgc3RybS5hdmFpbF9pbiA9IGhhdmU7CiAgICBzdGF0ZS5ob2xkID0gaG9sZDsKICAgIHN0YXRlLmJpdHMgPSBiaXRzOwogICAgLy8tLS0KCiAgICBpZiAoc3RhdGUud3NpemUgfHwgX291dCAhPT0gc3RybS5hdmFpbF9vdXQgJiYgc3RhdGUubW9kZSA8IEJBRCAmJiAoc3RhdGUubW9kZSA8IENIRUNLIHx8IGZsdXNoICE9PSBaX0ZJTklTSCQxKSkgewogICAgICBpZiAodXBkYXRld2luZG93KHN0cm0sIHN0cm0ub3V0cHV0LCBzdHJtLm5leHRfb3V0LCBfb3V0IC0gc3RybS5hdmFpbF9vdXQpKSA7CiAgICB9CiAgICBfaW4gLT0gc3RybS5hdmFpbF9pbjsKICAgIF9vdXQgLT0gc3RybS5hdmFpbF9vdXQ7CiAgICBzdHJtLnRvdGFsX2luICs9IF9pbjsKICAgIHN0cm0udG90YWxfb3V0ICs9IF9vdXQ7CiAgICBzdGF0ZS50b3RhbCArPSBfb3V0OwogICAgaWYgKHN0YXRlLndyYXAgJiYgX291dCkgewogICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAvKlVQREFURShzdGF0ZS5jaGVjaywgc3RybS5uZXh0X291dCAtIF9vdXQsIF9vdXQpOyovCiAgICAgIHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgc3RybS5uZXh0X291dCAtIF9vdXQpIDogYWRsZXIzMihzdGF0ZS5jaGVjaywgb3V0cHV0LCBfb3V0LCBzdHJtLm5leHRfb3V0IC0gX291dCk7CiAgICB9CiAgICBzdHJtLmRhdGFfdHlwZSA9IHN0YXRlLmJpdHMgKyAoc3RhdGUubGFzdCA/IDY0IDogMCkgKyAoc3RhdGUubW9kZSA9PT0gVFlQRSA/IDEyOCA6IDApICsgKHN0YXRlLm1vZGUgPT09IExFTl8gfHwgc3RhdGUubW9kZSA9PT0gQ09QWV8gPyAyNTYgOiAwKTsKICAgIGlmICgoX2luID09PSAwICYmIF9vdXQgPT09IDAgfHwgZmx1c2ggPT09IFpfRklOSVNIJDEpICYmIHJldCA9PT0gWl9PSyQxKSB7CiAgICAgIHJldCA9IFpfQlVGX0VSUk9SOwogICAgfQogICAgcmV0dXJuIHJldDsKICB9OwogIHZhciBpbmZsYXRlRW5kID0gZnVuY3Rpb24gaW5mbGF0ZUVuZChzdHJtKSB7CiAgICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUgLyp8fCBzdHJtLT56ZnJlZSA9PSAoZnJlZV9mdW5jKTAqLykgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTsKICAgIH0KICAgIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7CiAgICBpZiAoc3RhdGUud2luZG93KSB7CiAgICAgIHN0YXRlLndpbmRvdyA9IG51bGw7CiAgICB9CiAgICBzdHJtLnN0YXRlID0gbnVsbDsKICAgIHJldHVybiBaX09LJDE7CiAgfTsKICB2YXIgaW5mbGF0ZUdldEhlYWRlciA9IGZ1bmN0aW9uIGluZmxhdGVHZXRIZWFkZXIoc3RybSwgaGVhZCkgewogICAgLyogY2hlY2sgc3RhdGUgKi8KICAgIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTsKICAgIH0KICAgIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7CiAgICBpZiAoKHN0YXRlLndyYXAgJiAyKSA9PT0gMCkgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTsKICAgIH0KCiAgICAvKiBzYXZlIGhlYWRlciBzdHJ1Y3R1cmUgKi8KICAgIHN0YXRlLmhlYWQgPSBoZWFkOwogICAgaGVhZC5kb25lID0gZmFsc2U7CiAgICByZXR1cm4gWl9PSyQxOwogIH07CiAgdmFyIGluZmxhdGVTZXREaWN0aW9uYXJ5ID0gZnVuY3Rpb24gaW5mbGF0ZVNldERpY3Rpb25hcnkoc3RybSwgZGljdGlvbmFyeSkgewogICAgdmFyIGRpY3RMZW5ndGggPSBkaWN0aW9uYXJ5Lmxlbmd0aDsKICAgIHZhciBzdGF0ZTsKICAgIHZhciBkaWN0aWQ7CiAgICB2YXIgcmV0OwoKICAgIC8qIGNoZWNrIHN0YXRlICovCiAgICBpZiAoIXN0cm0gLyogPT0gWl9OVUxMICovIHx8ICFzdHJtLnN0YXRlIC8qID09IFpfTlVMTCAqLykgewogICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTsKICAgIH0KICAgIHN0YXRlID0gc3RybS5zdGF0ZTsKICAgIGlmIChzdGF0ZS53cmFwICE9PSAwICYmIHN0YXRlLm1vZGUgIT09IERJQ1QpIHsKICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7CiAgICB9CgogICAgLyogY2hlY2sgZm9yIGNvcnJlY3QgZGljdGlvbmFyeSBpZGVudGlmaWVyICovCiAgICBpZiAoc3RhdGUubW9kZSA9PT0gRElDVCkgewogICAgICBkaWN0aWQgPSAxOyAvKiBhZGxlcjMyKDAsIG51bGwsIDApKi8KICAgICAgLyogZGljdGlkID0gYWRsZXIzMihkaWN0aWQsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgpOyAqLwogICAgICBkaWN0aWQgPSBhZGxlcjMyKGRpY3RpZCwgZGljdGlvbmFyeSwgZGljdExlbmd0aCwgMCk7CiAgICAgIGlmIChkaWN0aWQgIT09IHN0YXRlLmNoZWNrKSB7CiAgICAgICAgcmV0dXJuIFpfREFUQV9FUlJPUiQxOwogICAgICB9CiAgICB9CiAgICAvKiBjb3B5IGRpY3Rpb25hcnkgdG8gd2luZG93IHVzaW5nIHVwZGF0ZXdpbmRvdygpLCB3aGljaCB3aWxsIGFtZW5kIHRoZQogICAgIGV4aXN0aW5nIGRpY3Rpb25hcnkgaWYgYXBwcm9wcmlhdGUgKi8KICAgIHJldCA9IHVwZGF0ZXdpbmRvdyhzdHJtLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCBkaWN0TGVuZ3RoKTsKICAgIGlmIChyZXQpIHsKICAgICAgc3RhdGUubW9kZSA9IE1FTTsKICAgICAgcmV0dXJuIFpfTUVNX0VSUk9SJDE7CiAgICB9CiAgICBzdGF0ZS5oYXZlZGljdCA9IDE7CiAgICAvLyBUcmFjZXYoKHN0ZGVyciwgImluZmxhdGU6ICAgZGljdGlvbmFyeSBzZXRcbiIpKTsKICAgIHJldHVybiBaX09LJDE7CiAgfTsKICBpbmZsYXRlJDMuaW5mbGF0ZVJlc2V0ID0gaW5mbGF0ZVJlc2V0OwogIGluZmxhdGUkMy5pbmZsYXRlUmVzZXQyID0gaW5mbGF0ZVJlc2V0MjsKICBpbmZsYXRlJDMuaW5mbGF0ZVJlc2V0S2VlcCA9IGluZmxhdGVSZXNldEtlZXA7CiAgaW5mbGF0ZSQzLmluZmxhdGVJbml0ID0gaW5mbGF0ZUluaXQ7CiAgaW5mbGF0ZSQzLmluZmxhdGVJbml0MiA9IGluZmxhdGVJbml0MjsKICBpbmZsYXRlJDMuaW5mbGF0ZSA9IGluZmxhdGUkMjsKICBpbmZsYXRlJDMuaW5mbGF0ZUVuZCA9IGluZmxhdGVFbmQ7CiAgaW5mbGF0ZSQzLmluZmxhdGVHZXRIZWFkZXIgPSBpbmZsYXRlR2V0SGVhZGVyOwogIGluZmxhdGUkMy5pbmZsYXRlU2V0RGljdGlvbmFyeSA9IGluZmxhdGVTZXREaWN0aW9uYXJ5OwogIGluZmxhdGUkMy5pbmZsYXRlSW5mbyA9ICdwYWtvIGluZmxhdGUgKGZyb20gTm9kZWNhIHByb2plY3QpJzsKCiAgLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyCiAgLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW4KICAvLwogIC8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkCiAgLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiAgLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KICAvLwogIC8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAogIC8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQKICAvLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAgLy8KICAvLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdAogIC8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKICAvLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogIC8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC4KICAvLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogIC8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgogIC8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgogIGZ1bmN0aW9uIEdaaGVhZGVyJDEoKSB7CiAgICAvKiB0cnVlIGlmIGNvbXByZXNzZWQgZGF0YSBiZWxpZXZlZCB0byBiZSB0ZXh0ICovCiAgICB0aGlzLnRleHQgPSAwOwogICAgLyogbW9kaWZpY2F0aW9uIHRpbWUgKi8KICAgIHRoaXMudGltZSA9IDA7CiAgICAvKiBleHRyYSBmbGFncyAobm90IHVzZWQgd2hlbiB3cml0aW5nIGEgZ3ppcCBmaWxlKSAqLwogICAgdGhpcy54ZmxhZ3MgPSAwOwogICAgLyogb3BlcmF0aW5nIHN5c3RlbSAqLwogICAgdGhpcy5vcyA9IDA7CiAgICAvKiBwb2ludGVyIHRvIGV4dHJhIGZpZWxkIG9yIFpfTlVMTCBpZiBub25lICovCiAgICB0aGlzLmV4dHJhID0gbnVsbDsKICAgIC8qIGV4dHJhIGZpZWxkIGxlbmd0aCAodmFsaWQgaWYgZXh0cmEgIT0gWl9OVUxMKSAqLwogICAgdGhpcy5leHRyYV9sZW4gPSAwOyAvLyBBY3R1YWxseSwgd2UgZG9uJ3QgbmVlZCBpdCBpbiBKUywKICAgIC8vIGJ1dCBsZWF2ZSBmb3IgZmV3IGNvZGUgbW9kaWZpY2F0aW9ucwoKICAgIC8vCiAgICAvLyBTZXR1cCBsaW1pdHMgaXMgbm90IG5lY2Vzc2FyeSBiZWNhdXNlIGluIGpzIHdlIHNob3VsZCBub3QgcHJlYWxsb2NhdGUgbWVtb3J5CiAgICAvLyBmb3IgaW5mbGF0ZSB1c2UgY29uc3RhbnQgbGltaXQgaW4gNjU1MzYgYnl0ZXMKICAgIC8vCgogICAgLyogc3BhY2UgYXQgZXh0cmEgKG9ubHkgd2hlbiByZWFkaW5nIGhlYWRlcikgKi8KICAgIC8vIHRoaXMuZXh0cmFfbWF4ICA9IDA7CiAgICAvKiBwb2ludGVyIHRvIHplcm8tdGVybWluYXRlZCBmaWxlIG5hbWUgb3IgWl9OVUxMICovCiAgICB0aGlzLm5hbWUgPSAnJzsKICAgIC8qIHNwYWNlIGF0IG5hbWUgKG9ubHkgd2hlbiByZWFkaW5nIGhlYWRlcikgKi8KICAgIC8vIHRoaXMubmFtZV9tYXggICA9IDA7CiAgICAvKiBwb2ludGVyIHRvIHplcm8tdGVybWluYXRlZCBjb21tZW50IG9yIFpfTlVMTCAqLwogICAgdGhpcy5jb21tZW50ID0gJyc7CiAgICAvKiBzcGFjZSBhdCBjb21tZW50IChvbmx5IHdoZW4gcmVhZGluZyBoZWFkZXIpICovCiAgICAvLyB0aGlzLmNvbW1fbWF4ICAgPSAwOwogICAgLyogdHJ1ZSBpZiB0aGVyZSB3YXMgb3Igd2lsbCBiZSBhIGhlYWRlciBjcmMgKi8KICAgIHRoaXMuaGNyYyA9IDA7CiAgICAvKiB0cnVlIHdoZW4gZG9uZSByZWFkaW5nIGd6aXAgaGVhZGVyIChub3QgdXNlZCB3aGVuIHdyaXRpbmcgYSBnemlwIGZpbGUpICovCiAgICB0aGlzLmRvbmUgPSBmYWxzZTsKICB9CiAgdmFyIGd6aGVhZGVyID0gR1poZWFkZXIkMTsKCiAgdmFyIHpsaWJfaW5mbGF0ZSA9IGluZmxhdGUkMzsKICB2YXIgdXRpbHMgPSBjb21tb247CiAgdmFyIHN0cmluZ3MgPSBzdHJpbmdzJDI7CiAgdmFyIG1zZyA9IG1lc3NhZ2VzOwogIHZhciBaU3RyZWFtID0genN0cmVhbTsKICB2YXIgR1poZWFkZXIgPSBnemhlYWRlcjsKICB2YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwoKICAvKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwogIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCgogIHZhciBaX05PX0ZMVVNIID0gY29uc3RhbnRzJDEuWl9OT19GTFVTSCwKICAgIFpfRklOSVNIID0gY29uc3RhbnRzJDEuWl9GSU5JU0gsCiAgICBaX09LID0gY29uc3RhbnRzJDEuWl9PSywKICAgIFpfU1RSRUFNX0VORCA9IGNvbnN0YW50cyQxLlpfU1RSRUFNX0VORCwKICAgIFpfTkVFRF9ESUNUID0gY29uc3RhbnRzJDEuWl9ORUVEX0RJQ1QsCiAgICBaX1NUUkVBTV9FUlJPUiA9IGNvbnN0YW50cyQxLlpfU1RSRUFNX0VSUk9SLAogICAgWl9EQVRBX0VSUk9SID0gY29uc3RhbnRzJDEuWl9EQVRBX0VSUk9SLAogICAgWl9NRU1fRVJST1IgPSBjb25zdGFudHMkMS5aX01FTV9FUlJPUjsKCiAgLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KCiAgLyoqCiAgICogY2xhc3MgSW5mbGF0ZQogICAqCiAgICogR2VuZXJpYyBKUy1zdHlsZSB3cmFwcGVyIGZvciB6bGliIGNhbGxzLiBJZiB5b3UgZG9uJ3QgbmVlZAogICAqIHN0cmVhbWluZyBiZWhhdmlvdXIgLSB1c2UgbW9yZSBzaW1wbGUgZnVuY3Rpb25zOiBbW2luZmxhdGVdXQogICAqIGFuZCBbW2luZmxhdGVSYXddXS4KICAgKiovCgogIC8qIGludGVybmFsCiAgICogaW5mbGF0ZS5jaHVua3MgLT4gQXJyYXkKICAgKgogICAqIENodW5rcyBvZiBvdXRwdXQgZGF0YSwgaWYgW1tJbmZsYXRlI29uRGF0YV1dIG5vdCBvdmVycmlkZGVuLgogICAqKi8KCiAgLyoqCiAgICogSW5mbGF0ZS5yZXN1bHQgLT4gVWludDhBcnJheXxTdHJpbmcKICAgKgogICAqIFVuY29tcHJlc3NlZCByZXN1bHQsIGdlbmVyYXRlZCBieSBkZWZhdWx0IFtbSW5mbGF0ZSNvbkRhdGFdXQogICAqIGFuZCBbW0luZmxhdGUjb25FbmRdXSBoYW5kbGVycy4gRmlsbGVkIGFmdGVyIHlvdSBwdXNoIGxhc3QgY2h1bmsKICAgKiAoY2FsbCBbW0luZmxhdGUjcHVzaF1dIHdpdGggYFpfRklOSVNIYCAvIGB0cnVlYCBwYXJhbSkuCiAgICoqLwoKICAvKioKICAgKiBJbmZsYXRlLmVyciAtPiBOdW1iZXIKICAgKgogICAqIEVycm9yIGNvZGUgYWZ0ZXIgaW5mbGF0ZSBmaW5pc2hlZC4gMCAoWl9PSykgb24gc3VjY2Vzcy4KICAgKiBTaG91bGQgYmUgY2hlY2tlZCBpZiBicm9rZW4gZGF0YSBwb3NzaWJsZS4KICAgKiovCgogIC8qKgogICAqIEluZmxhdGUubXNnIC0+IFN0cmluZwogICAqCiAgICogRXJyb3IgbWVzc2FnZSwgaWYgW1tJbmZsYXRlLmVycl1dICE9IDAKICAgKiovCgogIC8qKgogICAqIG5ldyBJbmZsYXRlKG9wdGlvbnMpCiAgICogLSBvcHRpb25zIChPYmplY3QpOiB6bGliIGluZmxhdGUgb3B0aW9ucy4KICAgKgogICAqIENyZWF0ZXMgbmV3IGluZmxhdG9yIGluc3RhbmNlIHdpdGggc3BlY2lmaWVkIHBhcmFtcy4gVGhyb3dzIGV4Y2VwdGlvbgogICAqIG9uIGJhZCBwYXJhbXMuIFN1cHBvcnRlZCBvcHRpb25zOgogICAqCiAgICogLSBgd2luZG93Qml0c2AKICAgKiAtIGBkaWN0aW9uYXJ5YAogICAqCiAgICogW2h0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZF0oaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkKQogICAqIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZXNlLgogICAqCiAgICogQWRkaXRpb25hbCBvcHRpb25zLCBmb3IgaW50ZXJuYWwgbmVlZHM6CiAgICoKICAgKiAtIGBjaHVua1NpemVgIC0gc2l6ZSBvZiBnZW5lcmF0ZWQgZGF0YSBjaHVua3MgKDE2SyBieSBkZWZhdWx0KQogICAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gZG8gcmF3IGluZmxhdGUKICAgKiAtIGB0b2AgKFN0cmluZykgLSBpZiBlcXVhbCB0byAnc3RyaW5nJywgdGhlbiByZXN1bHQgd2lsbCBiZSBjb252ZXJ0ZWQKICAgKiAgIGZyb20gdXRmOCB0byB1dGYxNiAoamF2YXNjcmlwdCkgc3RyaW5nLiBXaGVuIHN0cmluZyBvdXRwdXQgcmVxdWVzdGVkLAogICAqICAgY2h1bmsgbGVuZ3RoIGNhbiBkaWZmZXIgZnJvbSBgY2h1bmtTaXplYCwgZGVwZW5kaW5nIG9uIGNvbnRlbnQuCiAgICoKICAgKiBCeSBkZWZhdWx0LCB3aGVuIG5vIG9wdGlvbnMgc2V0LCBhdXRvZGV0ZWN0IGRlZmxhdGUvZ3ppcCBkYXRhIGZvcm1hdCB2aWEKICAgKiB3cmFwcGVyIGhlYWRlci4KICAgKgogICAqICMjIyMjIEV4YW1wbGU6CiAgICoKICAgKiBgYGBqYXZhc2NyaXB0CiAgICogY29uc3QgcGFrbyA9IHJlcXVpcmUoJ3Bha28nKQogICAqIGNvbnN0IGNodW5rMSA9IG5ldyBVaW50OEFycmF5KFsxLDIsMyw0LDUsNiw3LDgsOV0pCiAgICogY29uc3QgY2h1bmsyID0gbmV3IFVpbnQ4QXJyYXkoWzEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5XSk7CiAgICoKICAgKiBjb25zdCBpbmZsYXRlID0gbmV3IHBha28uSW5mbGF0ZSh7IGxldmVsOiAzfSk7CiAgICoKICAgKiBpbmZsYXRlLnB1c2goY2h1bmsxLCBmYWxzZSk7CiAgICogaW5mbGF0ZS5wdXNoKGNodW5rMiwgdHJ1ZSk7ICAvLyB0cnVlIC0+IGxhc3QgY2h1bmsKICAgKgogICAqIGlmIChpbmZsYXRlLmVycikgeyB0aHJvdyBuZXcgRXJyb3IoaW5mbGF0ZS5lcnIpOyB9CiAgICoKICAgKiBjb25zb2xlLmxvZyhpbmZsYXRlLnJlc3VsdCk7CiAgICogYGBgCiAgICoqLwogIGZ1bmN0aW9uIEluZmxhdGUkMShvcHRpb25zKSB7CiAgICB0aGlzLm9wdGlvbnMgPSB1dGlscy5hc3NpZ24oewogICAgICBjaHVua1NpemU6IDEwMjQgKiA2NCwKICAgICAgd2luZG93Qml0czogMTUsCiAgICAgIHRvOiAnJwogICAgfSwgb3B0aW9ucyB8fCB7fSk7CiAgICB2YXIgb3B0ID0gdGhpcy5vcHRpb25zOwoKICAgIC8vIEZvcmNlIHdpbmRvdyBzaXplIGZvciBgcmF3YCBkYXRhLCBpZiBub3Qgc2V0IGRpcmVjdGx5LAogICAgLy8gYmVjYXVzZSB3ZSBoYXZlIG5vIGhlYWRlciBmb3IgYXV0b2RldGVjdC4KICAgIGlmIChvcHQucmF3ICYmIG9wdC53aW5kb3dCaXRzID49IDAgJiYgb3B0LndpbmRvd0JpdHMgPCAxNikgewogICAgICBvcHQud2luZG93Qml0cyA9IC1vcHQud2luZG93Qml0czsKICAgICAgaWYgKG9wdC53aW5kb3dCaXRzID09PSAwKSB7CiAgICAgICAgb3B0LndpbmRvd0JpdHMgPSAtMTU7CiAgICAgIH0KICAgIH0KCiAgICAvLyBJZiBgd2luZG93Qml0c2Agbm90IGRlZmluZWQgKGFuZCBtb2RlIG5vdCByYXcpIC0gc2V0IGF1dG9kZXRlY3QgZmxhZyBmb3IgZ3ppcC9kZWZsYXRlCiAgICBpZiAob3B0LndpbmRvd0JpdHMgPj0gMCAmJiBvcHQud2luZG93Qml0cyA8IDE2ICYmICEob3B0aW9ucyAmJiBvcHRpb25zLndpbmRvd0JpdHMpKSB7CiAgICAgIG9wdC53aW5kb3dCaXRzICs9IDMyOwogICAgfQoKICAgIC8vIEd6aXAgaGVhZGVyIGhhcyBubyBpbmZvIGFib3V0IHdpbmRvd3Mgc2l6ZSwgd2UgY2FuIGRvIGF1dG9kZXRlY3Qgb25seQogICAgLy8gZm9yIGRlZmxhdGUuIFNvLCBpZiB3aW5kb3cgc2l6ZSBub3Qgc2V0LCBmb3JjZSBpdCB0byBtYXggd2hlbiBnemlwIHBvc3NpYmxlCiAgICBpZiAob3B0LndpbmRvd0JpdHMgPiAxNSAmJiBvcHQud2luZG93Qml0cyA8IDQ4KSB7CiAgICAgIC8vIGJpdCAzICgxNikgLT4gZ3ppcHBlZCBkYXRhCiAgICAgIC8vIGJpdCA0ICgzMikgLT4gYXV0b2RldGVjdCBnemlwL2RlZmxhdGUKICAgICAgaWYgKChvcHQud2luZG93Qml0cyAmIDE1KSA9PT0gMCkgewogICAgICAgIG9wdC53aW5kb3dCaXRzIHw9IDE1OwogICAgICB9CiAgICB9CiAgICB0aGlzLmVyciA9IDA7IC8vIGVycm9yIGNvZGUsIGlmIGhhcHBlbnMgKDAgPSBaX09LKQogICAgdGhpcy5tc2cgPSAnJzsgLy8gZXJyb3IgbWVzc2FnZQogICAgdGhpcy5lbmRlZCA9IGZhbHNlOyAvLyB1c2VkIHRvIGF2b2lkIG11bHRpcGxlIG9uRW5kKCkgY2FsbHMKICAgIHRoaXMuY2h1bmtzID0gW107IC8vIGNodW5rcyBvZiBjb21wcmVzc2VkIGRhdGEKCiAgICB0aGlzLnN0cm0gPSBuZXcgWlN0cmVhbSgpOwogICAgdGhpcy5zdHJtLmF2YWlsX291dCA9IDA7CiAgICB2YXIgc3RhdHVzID0gemxpYl9pbmZsYXRlLmluZmxhdGVJbml0Mih0aGlzLnN0cm0sIG9wdC53aW5kb3dCaXRzKTsKICAgIGlmIChzdGF0dXMgIT09IFpfT0spIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZ1tzdGF0dXNdKTsKICAgIH0KICAgIHRoaXMuaGVhZGVyID0gbmV3IEdaaGVhZGVyKCk7CiAgICB6bGliX2luZmxhdGUuaW5mbGF0ZUdldEhlYWRlcih0aGlzLnN0cm0sIHRoaXMuaGVhZGVyKTsKCiAgICAvLyBTZXR1cCBkaWN0aW9uYXJ5CiAgICBpZiAob3B0LmRpY3Rpb25hcnkpIHsKICAgICAgLy8gQ29udmVydCBkYXRhIGlmIG5lZWRlZAogICAgICBpZiAodHlwZW9mIG9wdC5kaWN0aW9uYXJ5ID09PSAnc3RyaW5nJykgewogICAgICAgIG9wdC5kaWN0aW9uYXJ5ID0gc3RyaW5ncy5zdHJpbmcyYnVmKG9wdC5kaWN0aW9uYXJ5KTsKICAgICAgfSBlbHNlIGlmICh0b1N0cmluZy5jYWxsKG9wdC5kaWN0aW9uYXJ5KSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJykgewogICAgICAgIG9wdC5kaWN0aW9uYXJ5ID0gbmV3IFVpbnQ4QXJyYXkob3B0LmRpY3Rpb25hcnkpOwogICAgICB9CiAgICAgIGlmIChvcHQucmF3KSB7CiAgICAgICAgLy9JbiByYXcgbW9kZSB3ZSBuZWVkIHRvIHNldCB0aGUgZGljdGlvbmFyeSBlYXJseQogICAgICAgIHN0YXR1cyA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlU2V0RGljdGlvbmFyeSh0aGlzLnN0cm0sIG9wdC5kaWN0aW9uYXJ5KTsKICAgICAgICBpZiAoc3RhdHVzICE9PSBaX09LKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnW3N0YXR1c10pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgLyoqCiAgICogSW5mbGF0ZSNwdXNoKGRhdGFbLCBmbHVzaF9tb2RlXSkgLT4gQm9vbGVhbgogICAqIC0gZGF0YSAoVWludDhBcnJheXxBcnJheUJ1ZmZlcik6IGlucHV0IGRhdGEKICAgKiAtIGZsdXNoX21vZGUgKE51bWJlcnxCb29sZWFuKTogMC4uNiBmb3IgY29ycmVzcG9uZGluZyBaX05PX0ZMVVNILi5aX1RSRUUKICAgKiAgIGZsdXNoIG1vZGVzLiBTZWUgY29uc3RhbnRzLiBTa2lwcGVkIG9yIGBmYWxzZWAgbWVhbnMgWl9OT19GTFVTSCwKICAgKiAgIGB0cnVlYCBtZWFucyBaX0ZJTklTSC4KICAgKgogICAqIFNlbmRzIGlucHV0IGRhdGEgdG8gaW5mbGF0ZSBwaXBlLCBnZW5lcmF0aW5nIFtbSW5mbGF0ZSNvbkRhdGFdXSBjYWxscyB3aXRoCiAgICogbmV3IG91dHB1dCBjaHVua3MuIFJldHVybnMgYHRydWVgIG9uIHN1Y2Nlc3MuIElmIGVuZCBvZiBzdHJlYW0gZGV0ZWN0ZWQsCiAgICogW1tJbmZsYXRlI29uRW5kXV0gd2lsbCBiZSBjYWxsZWQuCiAgICoKICAgKiBgZmx1c2hfbW9kZWAgaXMgbm90IG5lZWRlZCBmb3Igbm9ybWFsIG9wZXJhdGlvbiwgYmVjYXVzZSBlbmQgb2Ygc3RyZWFtCiAgICogZGV0ZWN0ZWQgYXV0b21hdGljYWxseS4gWW91IG1heSB0cnkgdG8gdXNlIGl0IGZvciBhZHZhbmNlZCB0aGluZ3MsIGJ1dAogICAqIHRoaXMgZnVuY3Rpb25hbGl0eSB3YXMgbm90IHRlc3RlZC4KICAgKgogICAqIE9uIGZhaWwgY2FsbCBbW0luZmxhdGUjb25FbmRdXSB3aXRoIGVycm9yIGNvZGUgYW5kIHJldHVybiBmYWxzZS4KICAgKgogICAqICMjIyMjIEV4YW1wbGUKICAgKgogICAqIGBgYGphdmFzY3JpcHQKICAgKiBwdXNoKGNodW5rLCBmYWxzZSk7IC8vIHB1c2ggb25lIG9mIGRhdGEgY2h1bmtzCiAgICogLi4uCiAgICogcHVzaChjaHVuaywgdHJ1ZSk7ICAvLyBwdXNoIGxhc3QgY2h1bmsKICAgKiBgYGAKICAgKiovCiAgSW5mbGF0ZSQxLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGRhdGEsIGZsdXNoX21vZGUpIHsKICAgIHZhciBzdHJtID0gdGhpcy5zdHJtOwogICAgdmFyIGNodW5rU2l6ZSA9IHRoaXMub3B0aW9ucy5jaHVua1NpemU7CiAgICB2YXIgZGljdGlvbmFyeSA9IHRoaXMub3B0aW9ucy5kaWN0aW9uYXJ5OwogICAgdmFyIHN0YXR1cywgX2ZsdXNoX21vZGUsIGxhc3RfYXZhaWxfb3V0OwogICAgaWYgKHRoaXMuZW5kZWQpIHJldHVybiBmYWxzZTsKICAgIGlmIChmbHVzaF9tb2RlID09PSB+fmZsdXNoX21vZGUpIF9mbHVzaF9tb2RlID0gZmx1c2hfbW9kZTtlbHNlIF9mbHVzaF9tb2RlID0gZmx1c2hfbW9kZSA9PT0gdHJ1ZSA/IFpfRklOSVNIIDogWl9OT19GTFVTSDsKCiAgICAvLyBDb252ZXJ0IGRhdGEgaWYgbmVlZGVkCiAgICBpZiAodG9TdHJpbmcuY2FsbChkYXRhKSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJykgewogICAgICBzdHJtLmlucHV0ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7CiAgICB9IGVsc2UgewogICAgICBzdHJtLmlucHV0ID0gZGF0YTsKICAgIH0KICAgIHN0cm0ubmV4dF9pbiA9IDA7CiAgICBzdHJtLmF2YWlsX2luID0gc3RybS5pbnB1dC5sZW5ndGg7CiAgICBmb3IgKDs7KSB7CiAgICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkgewogICAgICAgIHN0cm0ub3V0cHV0ID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmtTaXplKTsKICAgICAgICBzdHJtLm5leHRfb3V0ID0gMDsKICAgICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZTsKICAgICAgfQogICAgICBzdGF0dXMgPSB6bGliX2luZmxhdGUuaW5mbGF0ZShzdHJtLCBfZmx1c2hfbW9kZSk7CiAgICAgIGlmIChzdGF0dXMgPT09IFpfTkVFRF9ESUNUICYmIGRpY3Rpb25hcnkpIHsKICAgICAgICBzdGF0dXMgPSB6bGliX2luZmxhdGUuaW5mbGF0ZVNldERpY3Rpb25hcnkoc3RybSwgZGljdGlvbmFyeSk7CiAgICAgICAgaWYgKHN0YXR1cyA9PT0gWl9PSykgewogICAgICAgICAgc3RhdHVzID0gemxpYl9pbmZsYXRlLmluZmxhdGUoc3RybSwgX2ZsdXNoX21vZGUpOwogICAgICAgIH0gZWxzZSBpZiAoc3RhdHVzID09PSBaX0RBVEFfRVJST1IpIHsKICAgICAgICAgIC8vIFJlcGxhY2UgY29kZSB3aXRoIG1vcmUgdmVyYm9zZQogICAgICAgICAgc3RhdHVzID0gWl9ORUVEX0RJQ1Q7CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBTa2lwIHNueWMgbWFya2VycyBpZiBtb3JlIGRhdGEgZm9sbG93cyBhbmQgbm90IHJhdyBtb2RlCiAgICAgIHdoaWxlIChzdHJtLmF2YWlsX2luID4gMCAmJiBzdGF0dXMgPT09IFpfU1RSRUFNX0VORCAmJiBzdHJtLnN0YXRlLndyYXAgPiAwICYmIGRhdGFbc3RybS5uZXh0X2luXSAhPT0gMCkgewogICAgICAgIHpsaWJfaW5mbGF0ZS5pbmZsYXRlUmVzZXQoc3RybSk7CiAgICAgICAgc3RhdHVzID0gemxpYl9pbmZsYXRlLmluZmxhdGUoc3RybSwgX2ZsdXNoX21vZGUpOwogICAgICB9CiAgICAgIHN3aXRjaCAoc3RhdHVzKSB7CiAgICAgICAgY2FzZSBaX1NUUkVBTV9FUlJPUjoKICAgICAgICBjYXNlIFpfREFUQV9FUlJPUjoKICAgICAgICBjYXNlIFpfTkVFRF9ESUNUOgogICAgICAgIGNhc2UgWl9NRU1fRVJST1I6CiAgICAgICAgICB0aGlzLm9uRW5kKHN0YXR1cyk7CiAgICAgICAgICB0aGlzLmVuZGVkID0gdHJ1ZTsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQoKICAgICAgLy8gUmVtZW1iZXIgcmVhbCBgYXZhaWxfb3V0YCB2YWx1ZSwgYmVjYXVzZSB3ZSBtYXkgcGF0Y2ggb3V0IGJ1ZmZlciBjb250ZW50CiAgICAgIC8vIHRvIGFsaWduIHV0Zjggc3RyaW5ncyBib3VuZGFyaWVzLgogICAgICBsYXN0X2F2YWlsX291dCA9IHN0cm0uYXZhaWxfb3V0OwogICAgICBpZiAoc3RybS5uZXh0X291dCkgewogICAgICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCB8fCBzdGF0dXMgPT09IFpfU1RSRUFNX0VORCkgewogICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50byA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgdmFyIG5leHRfb3V0X3V0ZjggPSBzdHJpbmdzLnV0Zjhib3JkZXIoc3RybS5vdXRwdXQsIHN0cm0ubmV4dF9vdXQpOwogICAgICAgICAgICB2YXIgdGFpbCA9IHN0cm0ubmV4dF9vdXQgLSBuZXh0X291dF91dGY4OwogICAgICAgICAgICB2YXIgdXRmOHN0ciA9IHN0cmluZ3MuYnVmMnN0cmluZyhzdHJtLm91dHB1dCwgbmV4dF9vdXRfdXRmOCk7CgogICAgICAgICAgICAvLyBtb3ZlIHRhaWwgJiByZWFsaWduIGNvdW50ZXJzCiAgICAgICAgICAgIHN0cm0ubmV4dF9vdXQgPSB0YWlsOwogICAgICAgICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZSAtIHRhaWw7CiAgICAgICAgICAgIGlmICh0YWlsKSBzdHJtLm91dHB1dC5zZXQoc3RybS5vdXRwdXQuc3ViYXJyYXkobmV4dF9vdXRfdXRmOCwgbmV4dF9vdXRfdXRmOCArIHRhaWwpLCAwKTsKICAgICAgICAgICAgdGhpcy5vbkRhdGEodXRmOHN0cik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLm9uRGF0YShzdHJtLm91dHB1dC5sZW5ndGggPT09IHN0cm0ubmV4dF9vdXQgPyBzdHJtLm91dHB1dCA6IHN0cm0ub3V0cHV0LnN1YmFycmF5KDAsIHN0cm0ubmV4dF9vdXQpKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIE11c3QgcmVwZWF0IGl0ZXJhdGlvbiBpZiBvdXQgYnVmZmVyIGlzIGZ1bGwKICAgICAgaWYgKHN0YXR1cyA9PT0gWl9PSyAmJiBsYXN0X2F2YWlsX291dCA9PT0gMCkgY29udGludWU7CgogICAgICAvLyBGaW5hbGl6ZSBpZiBlbmQgb2Ygc3RyZWFtIHJlYWNoZWQuCiAgICAgIGlmIChzdGF0dXMgPT09IFpfU1RSRUFNX0VORCkgewogICAgICAgIHN0YXR1cyA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlRW5kKHRoaXMuc3RybSk7CiAgICAgICAgdGhpcy5vbkVuZChzdGF0dXMpOwogICAgICAgIHRoaXMuZW5kZWQgPSB0cnVlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmIChzdHJtLmF2YWlsX2luID09PSAwKSBicmVhazsKICAgIH0KICAgIHJldHVybiB0cnVlOwogIH07CgogIC8qKgogICAqIEluZmxhdGUjb25EYXRhKGNodW5rKSAtPiBWb2lkCiAgICogLSBjaHVuayAoVWludDhBcnJheXxTdHJpbmcpOiBvdXRwdXQgZGF0YS4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCwKICAgKiAgIGVhY2ggY2h1bmsgd2lsbCBiZSBzdHJpbmcuCiAgICoKICAgKiBCeSBkZWZhdWx0LCBzdG9yZXMgZGF0YSBibG9ja3MgaW4gYGNodW5rc1tdYCBwcm9wZXJ0eSBhbmQgZ2x1ZQogICAqIHRob3NlIGluIGBvbkVuZGAuIE92ZXJyaWRlIHRoaXMgaGFuZGxlciwgaWYgeW91IG5lZWQgYW5vdGhlciBiZWhhdmlvdXIuCiAgICoqLwogIEluZmxhdGUkMS5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24gKGNodW5rKSB7CiAgICB0aGlzLmNodW5rcy5wdXNoKGNodW5rKTsKICB9OwoKICAvKioKICAgKiBJbmZsYXRlI29uRW5kKHN0YXR1cykgLT4gVm9pZAogICAqIC0gc3RhdHVzIChOdW1iZXIpOiBpbmZsYXRlIHN0YXR1cy4gMCAoWl9PSykgb24gc3VjY2VzcywKICAgKiAgIG90aGVyIGlmIG5vdC4KICAgKgogICAqIENhbGxlZCBlaXRoZXIgYWZ0ZXIgeW91IHRlbGwgaW5mbGF0ZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0gaXMKICAgKiBjb21wbGV0ZSAoWl9GSU5JU0gpLiBCeSBkZWZhdWx0IC0gam9pbiBjb2xsZWN0ZWQgY2h1bmtzLAogICAqIGZyZWUgbWVtb3J5IGFuZCBmaWxsIGByZXN1bHRzYCAvIGBlcnJgIHByb3BlcnRpZXMuCiAgICoqLwogIEluZmxhdGUkMS5wcm90b3R5cGUub25FbmQgPSBmdW5jdGlvbiAoc3RhdHVzKSB7CiAgICAvLyBPbiBzdWNjZXNzIC0gam9pbgogICAgaWYgKHN0YXR1cyA9PT0gWl9PSykgewogICAgICBpZiAodGhpcy5vcHRpb25zLnRvID09PSAnc3RyaW5nJykgewogICAgICAgIHRoaXMucmVzdWx0ID0gdGhpcy5jaHVua3Muam9pbignJyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhpcy5yZXN1bHQgPSB1dGlscy5mbGF0dGVuQ2h1bmtzKHRoaXMuY2h1bmtzKTsKICAgICAgfQogICAgfQogICAgdGhpcy5jaHVua3MgPSBbXTsKICAgIHRoaXMuZXJyID0gc3RhdHVzOwogICAgdGhpcy5tc2cgPSB0aGlzLnN0cm0ubXNnOwogIH07CgogIC8qKgogICAqIGluZmxhdGUoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fFN0cmluZwogICAqIC0gZGF0YSAoVWludDhBcnJheSk6IGlucHV0IGRhdGEgdG8gZGVjb21wcmVzcy4KICAgKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgaW5mbGF0ZSBvcHRpb25zLgogICAqCiAgICogRGVjb21wcmVzcyBgZGF0YWAgd2l0aCBpbmZsYXRlL3VuZ3ppcCBhbmQgYG9wdGlvbnNgLiBBdXRvZGV0ZWN0CiAgICogZm9ybWF0IHZpYSB3cmFwcGVyIGhlYWRlciBieSBkZWZhdWx0LiBUaGF0J3Mgd2h5IHdlIGRvbid0IHByb3ZpZGUKICAgKiBzZXBhcmF0ZSBgdW5nemlwYCBtZXRob2QuCiAgICoKICAgKiBTdXBwb3J0ZWQgb3B0aW9ucyBhcmU6CiAgICoKICAgKiAtIHdpbmRvd0JpdHMKICAgKgogICAqIFtodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWRdKGh0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZCkKICAgKiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICAgKgogICAqIFN1Z2FyIChvcHRpb25zKToKICAgKgogICAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gc2F5IHRoYXQgd2Ugd29yayB3aXRoIHJhdyBzdHJlYW0sIGlmIHlvdSBkb24ndCB3aXNoIHRvIHNwZWNpZnkKICAgKiAgIG5lZ2F0aXZlIHdpbmRvd0JpdHMgaW1wbGljaXRseS4KICAgKiAtIGB0b2AgKFN0cmluZykgLSBpZiBlcXVhbCB0byAnc3RyaW5nJywgdGhlbiByZXN1bHQgd2lsbCBiZSBjb252ZXJ0ZWQKICAgKiAgIGZyb20gdXRmOCB0byB1dGYxNiAoamF2YXNjcmlwdCkgc3RyaW5nLiBXaGVuIHN0cmluZyBvdXRwdXQgcmVxdWVzdGVkLAogICAqICAgY2h1bmsgbGVuZ3RoIGNhbiBkaWZmZXIgZnJvbSBgY2h1bmtTaXplYCwgZGVwZW5kaW5nIG9uIGNvbnRlbnQuCiAgICoKICAgKgogICAqICMjIyMjIEV4YW1wbGU6CiAgICoKICAgKiBgYGBqYXZhc2NyaXB0CiAgICogY29uc3QgcGFrbyA9IHJlcXVpcmUoJ3Bha28nKTsKICAgKiBjb25zdCBpbnB1dCA9IHBha28uZGVmbGF0ZShuZXcgVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKSk7CiAgICogbGV0IG91dHB1dDsKICAgKgogICAqIHRyeSB7CiAgICogICBvdXRwdXQgPSBwYWtvLmluZmxhdGUoaW5wdXQpOwogICAqIH0gY2F0Y2ggKGVycikgewogICAqICAgY29uc29sZS5sb2coZXJyKTsKICAgKiB9CiAgICogYGBgCiAgICoqLwogIGZ1bmN0aW9uIGluZmxhdGUkMShpbnB1dCwgb3B0aW9ucykgewogICAgdmFyIGluZmxhdG9yID0gbmV3IEluZmxhdGUkMShvcHRpb25zKTsKICAgIGluZmxhdG9yLnB1c2goaW5wdXQpOwoKICAgIC8vIFRoYXQgd2lsbCBuZXZlciBoYXBwZW5zLCBpZiB5b3UgZG9uJ3QgY2hlYXQgd2l0aCBvcHRpb25zIDopCiAgICBpZiAoaW5mbGF0b3IuZXJyKSB0aHJvdyBpbmZsYXRvci5tc2cgfHwgbXNnW2luZmxhdG9yLmVycl07CiAgICByZXR1cm4gaW5mbGF0b3IucmVzdWx0OwogIH0KCiAgLyoqCiAgICogaW5mbGF0ZVJhdyhkYXRhWywgb3B0aW9uc10pIC0+IFVpbnQ4QXJyYXl8U3RyaW5nCiAgICogLSBkYXRhIChVaW50OEFycmF5KTogaW5wdXQgZGF0YSB0byBkZWNvbXByZXNzLgogICAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBpbmZsYXRlIG9wdGlvbnMuCiAgICoKICAgKiBUaGUgc2FtZSBhcyBbW2luZmxhdGVdXSwgYnV0IGNyZWF0ZXMgcmF3IGRhdGEsIHdpdGhvdXQgd3JhcHBlcgogICAqIChoZWFkZXIgYW5kIGFkbGVyMzIgY3JjKS4KICAgKiovCiAgZnVuY3Rpb24gaW5mbGF0ZVJhdyQxKGlucHV0LCBvcHRpb25zKSB7CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMucmF3ID0gdHJ1ZTsKICAgIHJldHVybiBpbmZsYXRlJDEoaW5wdXQsIG9wdGlvbnMpOwogIH0KCiAgLyoqCiAgICogdW5nemlwKGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheXxTdHJpbmcKICAgKiAtIGRhdGEgKFVpbnQ4QXJyYXkpOiBpbnB1dCBkYXRhIHRvIGRlY29tcHJlc3MuCiAgICogLSBvcHRpb25zIChPYmplY3QpOiB6bGliIGluZmxhdGUgb3B0aW9ucy4KICAgKgogICAqIEp1c3Qgc2hvcnRjdXQgdG8gW1tpbmZsYXRlXV0sIGJlY2F1c2UgaXQgYXV0b2RldGVjdHMgZm9ybWF0CiAgICogYnkgaGVhZGVyLmNvbnRlbnQuIERvbmUgZm9yIGNvbnZlbmllbmNlLgogICAqKi8KCiAgaW5mbGF0ZSQ0LkluZmxhdGUgPSBJbmZsYXRlJDE7CiAgaW5mbGF0ZSQ0LmluZmxhdGUgPSBpbmZsYXRlJDE7CiAgaW5mbGF0ZSQ0LmluZmxhdGVSYXcgPSBpbmZsYXRlUmF3JDE7CiAgaW5mbGF0ZSQ0LnVuZ3ppcCA9IGluZmxhdGUkMTsKICBpbmZsYXRlJDQuY29uc3RhbnRzID0gY29uc3RhbnRzJDE7CgogIHZhciBEZWZsYXRlID0gZGVmbGF0ZSQ0LkRlZmxhdGUsCiAgICBkZWZsYXRlID0gZGVmbGF0ZSQ0LmRlZmxhdGUsCiAgICBkZWZsYXRlUmF3ID0gZGVmbGF0ZSQ0LmRlZmxhdGVSYXcsCiAgICBnemlwID0gZGVmbGF0ZSQ0Lmd6aXA7CiAgdmFyIEluZmxhdGUgPSBpbmZsYXRlJDQuSW5mbGF0ZSwKICAgIGluZmxhdGUgPSBpbmZsYXRlJDQuaW5mbGF0ZSwKICAgIGluZmxhdGVSYXcgPSBpbmZsYXRlJDQuaW5mbGF0ZVJhdywKICAgIHVuZ3ppcCA9IGluZmxhdGUkNC51bmd6aXA7CiAgdmFyIGNvbnN0YW50cyA9IGNvbnN0YW50cyQxOwogIHBha28kMS5EZWZsYXRlID0gRGVmbGF0ZTsKICBwYWtvJDEuZGVmbGF0ZSA9IGRlZmxhdGU7CiAgcGFrbyQxLmRlZmxhdGVSYXcgPSBkZWZsYXRlUmF3OwogIHBha28kMS5nemlwID0gZ3ppcDsKICBwYWtvJDEuSW5mbGF0ZSA9IEluZmxhdGU7CiAgcGFrbyQxLmluZmxhdGUgPSBpbmZsYXRlOwogIHBha28kMS5pbmZsYXRlUmF3ID0gaW5mbGF0ZVJhdzsKICBwYWtvJDEudW5nemlwID0gdW5nemlwOwogIHBha28kMS5jb25zdGFudHMgPSBjb25zdGFudHM7CgogIHZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gaW50ZXJvcFJlcXVpcmVEZWZhdWx0OwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShsaWIsICJfX2VzTW9kdWxlIiwgewogICAgdmFsdWU6IHRydWUKICB9KTsKICB2YXIgZGVmYXVsdF8xID0gbGliLmRlZmF1bHQgPSB2b2lkIDA7CiAgdmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmplY3RTcHJlYWQyKTsKICB2YXIgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqZWN0V2l0aG91dFByb3BlcnRpZXMpOwogIHZhciBfY2xhc3NDYWxsQ2hlY2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChjbGFzc0NhbGxDaGVjayk7CiAgdmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KGNyZWF0ZUNsYXNzKTsKICB2YXIgX3R5cGVvZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90eXBlb2ZfMSk7CiAgdmFyIF9jb21wb25lbnRFbWl0dGVyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChjb21wb25lbnRFbWl0dGVyLmV4cG9ydHMpOwogIHZhciBfYmFja28gPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KGJhY2tvMik7CiAgdmFyIF9wYWtvID0gcGFrbyQxOwogIHZhciBfZXhjbHVkZWQgPSBbIm9wIl07CiAgLyogZXNsaW50LWRpc2FibGUgZXFlcWVxICovCiAgLy8gaW1wb3J0IHsgaXNGdW5jdGlvbiwgaXNVbmRlZmluZWQgfSBmcm9tICdAYmZlL2J5LWhlbHBlcnMnOwoKICB2YXIgb2JqZWN0UHJvdG8kMSA9IE9iamVjdC5wcm90b3R5cGU7CiAgdmFyIG9iamVjdFRvU3RyaW5nJDEgPSBvYmplY3RQcm90byQxLnRvU3RyaW5nOwogIHZhciBpc1VuZGVmaW5lZCA9IGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7CiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDsKICB9OwogIHZhciBpc09iamVjdCQxID0gZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHsKICAgIHZhciB0eXBlID0gKDAsIF90eXBlb2YyLmRlZmF1bHQpKHZhbHVlKTsKICAgIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpOwogIH07CiAgdmFyIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nOwogIHZhciBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nOwogIHZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkgewogICAgdmFyIHRhZyA9IGlzT2JqZWN0JDEodmFsdWUpID8gb2JqZWN0VG9TdHJpbmckMS5jYWxsKHZhbHVlKSA6ICcnOwogICAgcmV0dXJuIHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWc7CiAgfTsKICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIFdvcmtlciAhPT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIFdvcmtlckdsb2JhbFNjb3BlICE9PSAndW5kZWZpbmVkJykgewogICAgKDAsIF9jb21wb25lbnRFbWl0dGVyLmRlZmF1bHQpKFdlYlNvY2tldC5wcm90b3R5cGUpOwogIH0KCiAgLyogZXNsaW50LWRpc2FibGUgKi8KICB2YXIgV1MgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gV1ModXJpKSB7CiAgICAgIHZhciBvcHRzID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTsKICAgICAgKDAsIF9jbGFzc0NhbGxDaGVjazIuZGVmYXVsdCkodGhpcywgV1MpOwogICAgICAvLyBpZiAodXJpICYmICh0eXBlb2YgdXJpID09PSAnb2JqZWN0JykpIHsKICAgICAgLy8gICBvcHRzID0gdXJpOwogICAgICAvLyAgIHVyaSA9IG9wdHMudXJpOwogICAgICAvLyB9CiAgICAgIC8vIHRoaXMub3B0cyA9IG9wdHM7CiAgICAgIHZhciBkZWJ1ZyA9IG9wdHMuZGVidWcsCiAgICAgICAgY2xvc2VDb2RlID0gb3B0cy5jbG9zZUNvZGUsCiAgICAgICAgX29wdHMkYXV0b0Nvbm5lY3QgPSBvcHRzLmF1dG9Db25uZWN0LAogICAgICAgIGF1dG9Db25uZWN0ID0gX29wdHMkYXV0b0Nvbm5lY3QgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0cyRhdXRvQ29ubmVjdCwKICAgICAgICByZWNvbm5lY3Rpb25BdHRlbXB0cyA9IG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMsCiAgICAgICAgcmVjb25uZWN0aW9uRGVsYXkgPSBvcHRzLnJlY29ubmVjdGlvbkRlbGF5LAogICAgICAgIHJlY29ubmVjdGlvbkRlbGF5TWF4ID0gb3B0cy5yZWNvbm5lY3Rpb25EZWxheU1heCwKICAgICAgICByZWNvbm5lY3Rpb25SZXBvcnRUaHJlc2hvbGQgPSBvcHRzLnJlY29ubmVjdGlvblJlcG9ydFRocmVzaG9sZCwKICAgICAgICByZWNvbm5lY3Rpb25SZXBvcnRJbnRlcnZhbCA9IG9wdHMucmVjb25uZWN0aW9uUmVwb3J0SW50ZXJ2YWwsCiAgICAgICAgcmVjb25uZWN0aW9uUmVwb3J0TWF4ID0gb3B0cy5yZWNvbm5lY3Rpb25SZXBvcnRNYXgsCiAgICAgICAgcmFuZG9taXphdGlvbkZhY3RvciA9IG9wdHMucmFuZG9taXphdGlvbkZhY3RvciwKICAgICAgICB0aW1lb3V0ID0gb3B0cy50aW1lb3V0LAogICAgICAgIHJlY29ubmVjdGlvbiA9IG9wdHMucmVjb25uZWN0aW9uLAogICAgICAgIHByb3RvY29scyA9IG9wdHMucHJvdG9jb2xzLAogICAgICAgIGJpbmFyeVR5cGUgPSBvcHRzLmJpbmFyeVR5cGUsCiAgICAgICAgX29wdHMkbWF4SGVhcnRiZWF0RXJyID0gb3B0cy5tYXhIZWFydGJlYXRFcnJvck51bSwKICAgICAgICBtYXhIZWFydGJlYXRFcnJvck51bSA9IF9vcHRzJG1heEhlYXJ0YmVhdEVyciA9PT0gdm9pZCAwID8gMTAgOiBfb3B0cyRtYXhIZWFydGJlYXRFcnI7CiAgICAgIHRoaXMuY3VySGVhcnRiZWF0RXJyb3JOdW0gPSAwOwogICAgICB0aGlzLm1heEhlYXJ0YmVhdEVycm9yTnVtID0gbWF4SGVhcnRiZWF0RXJyb3JOdW07CiAgICAgIC8vIOWPr+iuvue9ruWPmOmHjwogICAgICB0aGlzLmNsb3NlQ29kZSA9IGlzVW5kZWZpbmVkKGNsb3NlQ29kZSkgPyBbMTAwMF0gOiBBcnJheS5pc0FycmF5KGNsb3NlQ29kZSkgPyBjbG9zZUNvZGUgOiBbY2xvc2VDb2RlXTsKICAgICAgdGhpcy51cmkgPSB1cmk7CiAgICAgIHRoaXMucHJvdG9jb2xzID0gcHJvdG9jb2xzOwogICAgICB0aGlzLmJpbmFyeVR5cGUgPSBiaW5hcnlUeXBlIHx8ICdhcnJheWJ1ZmZlcic7CiAgICAgIHRoaXMuZGVidWcgPSBkZWJ1ZyB8fCBmYWxzZTsKICAgICAgdGhpcy5hdXRvQ29ubmVjdCA9IGF1dG9Db25uZWN0OyAvLyDmmK/lkKboh6rliqjov57mjqUKICAgICAgdGhpcy5yZWNvbm5lY3Rpb24gPSByZWNvbm5lY3Rpb24gIT09IGZhbHNlOyAvLyDmmK/lkKboh6rliqjph43ov57vvIzpu5jorqR0cnVlCiAgICAgIHRoaXMucmVjb25uZWN0aW9uUmVwb3J0VGhyZXNob2xkID0gcmVjb25uZWN0aW9uUmVwb3J0VGhyZXNob2xkIHx8IDM7CiAgICAgIHRoaXMucmVjb25uZWN0aW9uUmVwb3J0SW50ZXJ2YWwgPSByZWNvbm5lY3Rpb25SZXBvcnRJbnRlcnZhbCB8fCAzOwogICAgICB0aGlzLnJlY29ubmVjdGlvblJlcG9ydE1heCA9IHJlY29ubmVjdGlvblJlcG9ydE1heCB8fCAyMjsKICAgICAgdGhpcy5yZWNvbm5lY3Rpb25BdHRlbXB0cyhyZWNvbm5lY3Rpb25BdHRlbXB0cyB8fCBJbmZpbml0eSk7IC8vIOacgOWkp+mHjei/nuasoeaVsAogICAgICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KHJlY29ubmVjdGlvbkRlbGF5IHx8IDEwMDApOyAvLyDpl7TpmpTml7bpl7QKICAgICAgdGhpcy5yZWNvbm5lY3Rpb25EZWxheU1heChyZWNvbm5lY3Rpb25EZWxheU1heCB8fCA1MDAwKTsgLy8g5pyA5aSn6Ze06ZqU5pe26Ze0CiAgICAgIHRoaXMucmFuZG9taXphdGlvbkZhY3RvcihyYW5kb21pemF0aW9uRmFjdG9yIHx8IDAuNSk7IC8vIOmXtOmalOmaj+acuuWinumVv+aVsAogICAgICB0aGlzLmJhY2tvZmYgPSBuZXcgX2JhY2tvLmRlZmF1bHQoewogICAgICAgIG1pbjogdGhpcy5yZWNvbm5lY3Rpb25EZWxheSgpLAogICAgICAgIG1heDogdGhpcy5yZWNvbm5lY3Rpb25EZWxheU1heCgpLAogICAgICAgIGppdHRlcjogdGhpcy5yYW5kb21pemF0aW9uRmFjdG9yKCkKICAgICAgfSk7CiAgICAgIHRoaXMudGltZW91dCh0aW1lb3V0IHx8IDEwMDAwKTsgLy8g6LaF5pe25pe26Ze06K6+572uIG1zCgogICAgICAvLyDlhoXpg6jlj5jph48KICAgICAgdGhpcy4kaXNQYWdlQWN0aXZlID0gdHJ1ZTsgLy8g6aG16Z2i5piv5ZCm5Y+v6KeBCiAgICAgIHRoaXMuZW5naW5lID0gbnVsbDsgLy8gd2Vic29ja2V0CiAgICAgIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7IC8vIOaYr+WQpuW3sui/nuaOpQogICAgICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJzsgLy8g5b2T5YmN54q25oCBCiAgICAgIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7IC8vIOato+WcqOmHjei/ngogICAgICB0aGlzLnNraXBSZWNvbmVjdCA9IGZhbHNlOwogICAgICB0aGlzLnBpbmdJbnRlcnZhbFRpbWVyID0gbnVsbDsgLy8gcGluZyB0aW1lcgogICAgICB0aGlzLnBpbmdUaW1lb3V0VGltZXIgPSBudWxsOyAvLyBwaW5nIHRpbWVvdXQgVGltZXIKICAgICAgdGhpcy5oZWFydEVycm9yID0gZmFsc2U7CiAgICAgIC8vIG5vdGU6IG3nq5nlv4Pot7PmnLrliLYKICAgICAgdGhpcy5waW5nSW50ZXJ2YWwgPSAxNTAwMDsKICAgICAgdGhpcy5waW5nVGltZW91dCA9IDMwMDA7CiAgICAgIHRoaXMuZXYgPSBbXTsgLy8g5YaF6YOo5LqL5Lu26K6i6ZiFCiAgICAgIC8vIHRoaXMuc3VicyA9IFtdOyAvLyDorqLpmIV0b3BpY+aVsOe7hAogICAgICAvLyB0aGlzLnRvcGljQXJyID0gW107IC8vIOiuoumYhXRvcGljIOaVsOe7hAogICAgICAvLyDpnIDopoHoh6rliqjph43ov57vvIzliJnosIPnlKhvcGVuKCkKICAgICAgdGhpcy5jb25uZWN0U3RhcnQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKICAgICAgdGhpcy5vcGVuU3RhcnQgPSBudWxsOwogICAgICBpZiAodGhpcy5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7CiAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnJWNbc29ja2V0XScsICdjb2xvcjogIzQ5YzljOTsnLCAn5Yib5bu6IHNvY2tldCDlrp7kvosnKTsKICAgIH0KICAgIHJldHVybiAoMCwgX2NyZWF0ZUNsYXNzMi5kZWZhdWx0KShXUywgW3sKICAgICAga2V5OiAiY2hhbmdlVXJsIiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNoYW5nZVVybCh1cmkpIHsKICAgICAgICB0aGlzLnVyaSA9IHVyaTsKICAgICAgfQogICAgfSwgewogICAgICBrZXk6ICJnZXRVcmwiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VXJsKCkgewogICAgICAgIHZhciB1cmkgPSB0aGlzLnVyaTsKICAgICAgICByZXR1cm4gaXNGdW5jdGlvbih1cmkpID8gdXJpKCkgOiB1cmk7CiAgICAgIH0KICAgIH0sIHsKICAgICAga2V5OiAib3BlbiIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiBvcGVuKCkgewogICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwogICAgICAgIHRoaXMub3BlblN0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7CiAgICAgICAgLy8gY29uc3Qgc2VsZiA9IHRoaXM7CiAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCclY1tzb2NrZXRdJywgJ2NvbG9yOiAjNDljOWM5OycsICdvcGVuIOW8gOWni+eKtuaAgTonLCB0aGlzLnJlYWR5U3RhdGUsICfov57mjqXlnLDlnYDvvJonLCB0aGlzLmdldFVybCgpKTsKICAgICAgICBpZiAofnRoaXMucmVhZHlTdGF0ZS5pbmRleE9mKCdvcGVuJykpIHJldHVybjsKICAgICAgICB0cnkgewogICAgICAgICAgLy8gMjAyMS0xMS0xOSBzYWZhcmkgMTUuMem7mOiupOW8gOWQryBOU1VSTCBTZXNzaW9uIFdlYnNvY2tldCwg5aSn5YyF5Lya6Ieq5Yqo5YiG54mH77yM5LiN5pSv5oyB5a6i5oi356uv5Li75Yqo5YWz6Zet6L+e5o6l77yM55uu5YmN5Yik5pat5paw54mI5pys5YqgYz0wIOS4jeW8gOWQr+WOi+e8qQogICAgICAgICAgdmFyIHNhZmFyaSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvdmVyc2lvblwvKFtcZC5dKykuKnNhZmFyaS8pOwogICAgICAgICAgdmFyIGVuY29kaW5nID0gc2FmYXJpICYmIE51bWJlcihzYWZhcmlbMV0pID49IDE1LjEgPyAnJmM9MCcgOiAnJzsKICAgICAgICAgIHZhciB1cmwgPSAvXD8vLnRlc3QodGhpcy5nZXRVcmwoKSkgPyAiIi5jb25jYXQodGhpcy5nZXRVcmwoKSwgIiZ0aW1lc3RhbXA9IikuY29uY2F0KG5ldyBEYXRlKCkuZ2V0VGltZSgpKS5jb25jYXQoZW5jb2RpbmcpIDogIiIuY29uY2F0KHRoaXMuZ2V0VXJsKCksICI/dGltZXN0YW1wPSIpLmNvbmNhdChuZXcgRGF0ZSgpLmdldFRpbWUoKSkuY29uY2F0KGVuY29kaW5nKTsKICAgICAgICAgIC8vIHRvZG86IOWinuWKoHRpbWVzdGFtcOWPguaVsOavlOi+g+eUn+ehrAogICAgICAgICAgdGhpcy5lbmdpbmUgPSBuZXcgV2ViU29ja2V0KHVybCwgdGhpcy5wcm90b2NvbHMpOwogICAgICAgICAgdGhpcy5lbmdpbmUuYmluYXJ5VHlwZSA9IHRoaXMuYmluYXJ5VHlwZTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgewogICAgICAgICAgICBjb25zb2xlLmVycm9yKCdbc29ja2V0XeWIm+W7uuWunuS+i+WPkeeUn+mUmeivrycsIGUpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5lbWl0KCdvcGVuX2Vycm9yJywgewogICAgICAgICAgICBjb2RlOiA0OTk4LAogICAgICAgICAgICByZWFzb246IGUubWVzc2FnZSB8fCBlCiAgICAgICAgICB9KTsgLy8gcmVwb3J0CiAgICAgICAgfQogICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJzsKICAgICAgICB0aGlzLnNraXBSZWNvbmVjdCA9IGZhbHNlOwogICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTsKICAgICAgICAvLyDmt7vliqDpk77mjqXotoXml7bmnLrliLbvvIxpT1Mg5bmz5Y+w5LiN5Lya6KKr5Yqo6Kem5Y+RIGVycm9yIOS6i+S7tgogICAgICAgIGlmICh0aGlzLl90aW1lb3V0KSB7CiAgICAgICAgICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXQ7CiAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJyVjW3NvY2tldF0nLCAnY29sb3I6ICM0OWM5Yzk7JywgJ+i2heaXtuWwhuWcqOW8gOWni+mHjei/nicsIHRpbWVvdXQpOwogICAgICAgICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIHRvZG8gb25lcnJvcuayoeacieaOpeaUtgogICAgICAgICAgICBfdGhpczIuZW5naW5lICYmIF90aGlzMi5lbmdpbmUuZW1pdCgnb3Blbl90aW1lb3V0JywgewogICAgICAgICAgICAgIGNvZGU6IDQ5OTcsCiAgICAgICAgICAgICAgcmVhc29uOiAnb3Blbl90aW1lb3V0JwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgX3RoaXMyLmVtaXQoJ2Nvbm5lY3RfdGltZW91dCcsIHRpbWVvdXQpOwogICAgICAgICAgfSwgdGltZW91dCk7CiAgICAgICAgICB0aGlzLmV2LnB1c2goewogICAgICAgICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkgewogICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfSwgewogICAgICBrZXk6ICJzZW5kIiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNlbmQob2JqKSB7CiAgICAgICAgaWYgKHRoaXMuY29ubmVjdGVkKSB7CiAgICAgICAgICB0aGlzLmVuZ2luZS5zZW5kKEpTT04uc3RyaW5naWZ5KG9iaikpOwogICAgICAgIH0KICAgICAgfQogICAgfSwgewogICAgICBrZXk6ICJjbG9zZSIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbG9zZSgpIHsKICAgICAgICB2YXIgY29kZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogMTAwNTsKICAgICAgICB0aGlzLm9uQ2xvc2UoewogICAgICAgICAgY29kZTogY29kZSwKICAgICAgICAgIHJlYXNvbjogJ2Nsb3NlX2J5X3VzZXInCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIC8qIHByaXZhdGUgZnVuY3Rpb24gKi8KICAgIH0sIHsKICAgICAga2V5OiAib25PcGVuIiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIG9uT3BlbigpIHsKICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJyVjW3NvY2tldF0nLCAnY29sb3I6ICM0OWM5Yzk7JywgJ1dTIHByb3RvdHlwZSBvbk9wZW4g5omn6KGMJyk7CiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nOwogICAgICAgIHRoaXMuY2xlYXJFVigpOwogICAgICAgIHRoaXMuc2V0UGluZygpOwogICAgICAgIHRoaXMuY29ubmVjdGVkID0gdHJ1ZTsKICAgICAgICBpZiAodGhpcy5yZWNvbm5lY3RpbmcpIHsKICAgICAgICAgIHZhciBhdHRlbXB0ID0gdGhpcy5iYWNrb2ZmLmF0dGVtcHRzOwogICAgICAgICAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTsKICAgICAgICAgIHRoaXMuYmFja29mZi5yZXNldCgpOwogICAgICAgICAgdGhpcy5lbWl0KCdyZWNvbm5lY3QnLCBhdHRlbXB0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhpcy5lbWl0KCdjb25uZWN0Jyk7CiAgICAgICAgfQogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogIm9uRGF0YSIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbkRhdGEoZGF0YSkgewogICAgICAgIHZhciByZXRfbXNnID0gZGF0YS5yZXRfbXNnLAogICAgICAgICAgdG9waWMgPSBkYXRhLnRvcGljLAogICAgICAgICAgcmVxdWVzdCA9IGRhdGEucmVxdWVzdCwKICAgICAgICAgIHN1Y2Nlc3MgPSBkYXRhLnN1Y2Nlc3MsCiAgICAgICAgICB0eXBlID0gZGF0YS50eXBlLAogICAgICAgICAgY29ubl9pZCA9IGRhdGEuY29ubl9pZCwKICAgICAgICAgIHBpbmcgPSBkYXRhLnBpbmcsCiAgICAgICAgICBvcCA9IGRhdGEub3AsCiAgICAgICAgICB0aW1lc3RhbXBFNiA9IGRhdGEudGltZXN0YW1wRTYsCiAgICAgICAgICB0aW1lc3RhbXBfZTYgPSBkYXRhLnRpbWVzdGFtcF9lNjsKICAgICAgICAvLyDlhbzlrrnnjrDotKflkozlkIjnuqbnmoRzZXJ2ZXIgcGluZyDmoLzlvI8KICAgICAgICBpZiAocGluZykgewogICAgICAgICAgdGhpcy5zZW5kKHsKICAgICAgICAgICAgcG9uZzogcGluZwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmIChvcCA9PT0gJ3BpbmcnKSB7CiAgICAgICAgICBkYXRhLm9wOwogICAgICAgICAgICB2YXIgb3RoZXIgPSAoMCwgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzMi5kZWZhdWx0KShkYXRhLCBfZXhjbHVkZWQpOwogICAgICAgICAgdGhpcy5zZW5kKCgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7CiAgICAgICAgICAgIG9wOiAncG9uZycKICAgICAgICAgIH0sIG90aGVyKSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmIChyZXRfbXNnID09PSAncG9uZycpIHsKICAgICAgICAgIHRoaXMuY3VySGVhcnRiZWF0RXJyb3JOdW0gPSAwOwogICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ1RpbWVvdXRUaW1lcik7CiAgICAgICAgICB2YXIgbm93ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7CiAgICAgICAgICByZXF1ZXN0Lm9wOwogICAgICAgICAgICB2YXIgYXJncyA9IHJlcXVlc3QuYXJnczsKICAgICAgICAgIHZhciByZXFUaW1lID0gYXJnc1swXTsKICAgICAgICAgIGlmIChyZXFUaW1lKSB7CiAgICAgICAgICAgIGlmIChub3cgLSByZXFUaW1lIDwgMzAwMCkgewogICAgICAgICAgICAgIGlmICh0aGlzLmhlYXJ0RXJyb3IpIHsKICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnaGVhcnRfYmFjaycsIHsKICAgICAgICAgICAgICAgICAgY29kZTogNDk5NSwKICAgICAgICAgICAgICAgICAgcmVhc29uOiAnaGVhcnRfYmFjaycKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgdGhpcy5oZWFydEVycm9yID0gZmFsc2U7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLnNldFBpbmcoKTsKICAgICAgICB9IGVsc2UgaWYgKHRvcGljKSB7CiAgICAgICAgICB0aGlzLmVtaXQodG9waWMsIHsKICAgICAgICAgICAgdHlwZTogdHlwZSwKICAgICAgICAgICAgZGF0YTogZGF0YS5kYXRhLAogICAgICAgICAgICB0aW1lc3RhbXBFNjogdGltZXN0YW1wX2U2IHx8IHRpbWVzdGFtcEU2CiAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKHJlcXVlc3QpIHsKICAgICAgICAgIHZhciBfb3AzID0gcmVxdWVzdC5vcDsKICAgICAgICAgIGlmIChzdWNjZXNzKSB7CiAgICAgICAgICAgIHRoaXMuZW1pdCgiIi5jb25jYXQoX29wMywgIl9zdWNjZXNzIiksIGNvbm5faWQpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy5lbWl0KCIiLmNvbmNhdChfb3AzLCAiX2ZhaWwiKSwgY29ubl9pZCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpOwogICAgICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlJywgZGF0YSk7CiAgICAgICAgfQogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogIm9uQ2xvc2UiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gb25DbG9zZShfcmVmKSB7CiAgICAgICAgdmFyIGNvZGUgPSBfcmVmLmNvZGUsCiAgICAgICAgICByZWFzb24gPSBfcmVmLnJlYXNvbjsKICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJyVjW3NvY2tldF0nLCAnY29sb3I6ICM0OWM5Yzk7JywgJ1dTIHByb3RvdHlwZSBvbkNsb3NlIOaJp+ihjDonLCByZWFzb24pOwogICAgICAgIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7CiAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTsKICAgICAgICAvLyBjbGVhciB0aW1lcnMKICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nSW50ZXJ2YWxUaW1lcik7CiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ1RpbWVvdXRUaW1lcik7CgogICAgICAgIC8vIDEwMDbkv53nlZljb2RlCiAgICAgICAgdmFyIGMgPSBjb2RlOwogICAgICAgIGlmIChjID09PSAxMDA2KSB7CiAgICAgICAgICBjID0gNDAwNjsKICAgICAgICB9IGVsc2UgaWYgKGMgPT09IDEwMDUpIHsKICAgICAgICAgIGMgPSA0MDA1OwogICAgICAgIH0KICAgICAgICAvLyBGaXJlZm94IHdpbGwgdGhyb3cgZXJyb3Igd2hlbiB3cyBjbG9zZWQgbm9ybWFsbHkgdXNpbmcgMTAwMQogICAgICAgIGlmIChjb2RlICE9PSAxMDAxKSB0aGlzLmVuZ2luZS5jbG9zZShjKTsKICAgICAgICB0aGlzLmNsZWFyVXAoKTsKICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJzsKICAgICAgICB0aGlzLmVtaXQoJ2Nsb3NlJywgewogICAgICAgICAgY29kZTogY29kZSwKICAgICAgICAgIHJlYXNvbjogcmVhc29uCiAgICAgICAgfSk7CgogICAgICAgIC8vIOeUqOaIt+S4u+WKqOWFs+mXreS4jei/m+ihjOmHjei/nu+8jGBjbG9zZUNvZGVgIOWPr+S7peiHquihjOmFjee9ru+8jOaUr+aMgSBgMGAg77yM6YWN572uIGBbXWAg5pe25rC46L+c6YeN6L+eCiAgICAgICAgaWYgKHRoaXMuY2xvc2VDb2RlLmluY2x1ZGVzKGNvZGUpKSB7CiAgICAgICAgICB0aGlzLnNraXBSZWNvbmVjdCA9IHRydWU7CiAgICAgICAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlOwogICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZF91c2VyJzsKICAgICAgICAgIHRoaXMuYmFja29mZi5yZXNldCgpOwogICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCclY1tzb2NrZXRdJywgJ2NvbG9yOiAjNDljOWM5OycsICfnlKjmiLfkuLvliqjlhbPpl60nLCByZWFzb24pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodGhpcy5yZWNvbm5lY3Rpb24gJiYgIXRoaXMuc2tpcFJlY29uZWN0KSB7CiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogIm9uRXJyb3IiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gb25FcnJvcihlcnIpIHsKICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJyVjW3NvY2tldF0nLCAnY29sb3I6ICM0OWM5Yzk7JywgJ29uRXJyb3Ig5omn6KGMOicsIGVycik7CiAgICAgICAgdGhpcy5jbGVhclVwKCk7CiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7CiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7CiAgICAgICAgdGhpcy5vbkNsb3NlKGVycik7CiAgICAgIH0KICAgIH0sIHsKICAgICAga2V5OiAic2V0UGFnZUFjdGl2ZSIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRQYWdlQWN0aXZlKGlzQWN0aXZlKSB7CiAgICAgICAgdGhpcy4kaXNQYWdlQWN0aXZlID0gaXNBY3RpdmU7CiAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCclY1tzb2NrZXRdJywgJ2NvbG9yOiAjNDljOWM5OycsICfpobXpnaLlj6/op4HvvIzmiafooYzph43ov57mo4DmtYsnKTsKICAgICAgICAvLyDpobXpnaLmv4DmtLvml7bvvIzph43ov54KICAgICAgICBpZiAoIXRoaXMuY29ubmVjdGVkICYmIHRoaXMuJGlzUGFnZUFjdGl2ZSkgewogICAgICAgICAgdGhpcy5yZWNvbm5lY3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0sIHsKICAgICAga2V5OiAicmVjb25uZWN0IiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlY29ubmVjdCgpIHsKICAgICAgICB2YXIgX3RoaXMzID0gdGhpczsKICAgICAgICB0aGlzLmVtaXQoJ3JlY29ubmVjdF9zdGFydCcpOwogICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnJWNbc29ja2V0XScsICdjb2xvcjogIzQ5YzljOTsnLCAnV1MgcHJvdG90eXBlIHJlY29ubmVjdCDmiafooYw6Jyk7CiAgICAgICAgaWYgKHRoaXMucmVjb25uZWN0aW5nIHx8IHRoaXMuc2tpcFJlY29uZWN0IHx8ICF0aGlzLiRpc1BhZ2VBY3RpdmUpIHsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKHRoaXMuYmFja29mZi5hdHRlbXB0cyA+IHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzKSB7CiAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5lcnJvcignW3NvY2tldF3otoXov4fmnIDlpKfph43ov57mrKHmlbAsIOmHjei/nuW9u+W6leWksei0pScpOwogICAgICAgICAgLy8gY2xlYXIgdGltZXJzCiAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nSW50ZXJ2YWxUaW1lcik7CiAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTsKCiAgICAgICAgICAvLyByZW1vdmUKICAgICAgICAgIHRoaXMuZW5naW5lLmNsb3NlKCk7CiAgICAgICAgICB0aGlzLmNsZWFyVXAoKTsKICAgICAgICAgIHRoaXMuYmFja29mZi5yZXNldCgpOwogICAgICAgICAgdGhpcy5lbWl0KCdyZWNvbm5lY3RfZmFpbGVkJyk7CiAgICAgICAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB2YXIgZGVsYXkgPSB0aGlzLmJhY2tvZmYuZHVyYXRpb24oKTsKICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnJWNbc29ja2V0XScsICdjb2xvcjogIzQ5YzljOTsnLCAn56ys5Yeg5qyh6YeN6L+e77yaJywgdGhpcy5iYWNrb2ZmLmF0dGVtcHRzLCAn562J5b6FICVkbXMg5byA5aeL5Y+R6LW36YeN6L+e77yaJywgZGVsYXkpOwogICAgICAgICAgdGhpcy5yZWNvbm5lY3RpbmcgPSB0cnVlOwogICAgICAgICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmIChfdGhpczMuc2tpcFJlY29uZWN0KSByZXR1cm47CiAgICAgICAgICAgIF90aGlzMy5lbWl0KCdyZWNvbm5lY3RfYXR0ZW1wdCcsIF90aGlzMy5iYWNrb2ZmLmF0dGVtcHRzKTsgLy8g5Y+R6YCBIOmHjei/nuasoeaVsCDkuovku7YKICAgICAgICAgICAgX3RoaXMzLmVtaXQoJ3JlY29ubmVjdGluZycsIF90aGlzMy5iYWNrb2ZmLmF0dGVtcHRzKTsgLy8g5Y+R6YCB5LqL5Lu2CgogICAgICAgICAgICBpZiAoX3RoaXMzLmJhY2tvZmYuYXR0ZW1wdHMgPiBfdGhpczMucmVjb25uZWN0aW9uUmVwb3J0VGhyZXNob2xkICYmIF90aGlzMy5iYWNrb2ZmLmF0dGVtcHRzICUgX3RoaXMzLnJlY29ubmVjdGlvblJlcG9ydEludGVydmFsID09PSAwICYmIF90aGlzMy5iYWNrb2ZmLmF0dGVtcHRzIDwgX3RoaXMzLnJlY29ubmVjdGlvblJlcG9ydE1heCkgewogICAgICAgICAgICAgIF90aGlzMy5lbWl0KCdyZWNvbm5lY3RfcmVwb3J0JywgX3RoaXMzLmJhY2tvZmYuYXR0ZW1wdHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF90aGlzMy5vcGVuKCk7CiAgICAgICAgICB9LCBkZWxheSk7CiAgICAgICAgICAvLyDkuovku7bnu4QKICAgICAgICAgIHRoaXMuZXYucHVzaCh7CiAgICAgICAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7CiAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogInBpbmciLAogICAgICB2YWx1ZTogZnVuY3Rpb24gcGluZygpIHsKICAgICAgICB0aGlzLnNlbmQoewogICAgICAgICAgb3A6ICdwaW5nJywKICAgICAgICAgIGFyZ3M6IFtuZXcgRGF0ZSgpLmdldFRpbWUoKV0KICAgICAgICB9KTsKICAgICAgfQoKICAgICAgLy8gcmVzZXQgcGluZyB0aW1lb3V0CiAgICB9LCB7CiAgICAgIGtleTogIm9uSGVhcnRiZWF0IiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIG9uSGVhcnRiZWF0KHRpbWVvdXQpIHsKICAgICAgICB2YXIgX3RoaXM0ID0gdGhpczsKICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTsKICAgICAgICB0aGlzLnBpbmdUaW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgIGlmIChfdGhpczQucmVhZHlTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHJldHVybjsKICAgICAgICAgIC8vIHRoaXMub25DbG9zZSh7IGNvZGU6IDQ5OTYsIHJlYXNvbjogJ3BpbmcgdGltZW91dCcgfSk7CiAgICAgICAgICBfdGhpczQuZW1pdCgnaGVhcnRfZXJyb3InLCB7CiAgICAgICAgICAgIGNvZGU6IDQ5OTYsCiAgICAgICAgICAgIHJlYXNvbjogJ3BpbmcgdGltZW91dCcKICAgICAgICAgIH0pOwogICAgICAgICAgX3RoaXM0LmhlYXJ0RXJyb3IgPSB0cnVlOwogICAgICAgICAgaWYgKF90aGlzNC5tYXhIZWFydGJlYXRFcnJvck51bSkgewogICAgICAgICAgICBfdGhpczQuY3VySGVhcnRiZWF0RXJyb3JOdW0gKz0gMTsKICAgICAgICAgICAgaWYgKF90aGlzNC5jdXJIZWFydGJlYXRFcnJvck51bSA+PSBfdGhpczQubWF4SGVhcnRiZWF0RXJyb3JOdW0pIHsKICAgICAgICAgICAgICBfdGhpczQuZW1pdCgnaGVhcnRfc3RvcCcsIHsKICAgICAgICAgICAgICAgIGNvZGU6IDQ5OTQsCiAgICAgICAgICAgICAgICByZWFzb246ICdwaW5nIHRpbWVvdXQgLSBoZWFydCBzdG9wJwogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgIF90aGlzNC5vbkNsb3NlKHsKICAgICAgICAgICAgICAgIHJlYXNvbjogJ2hlYXJ0YmVhdCBzdG9wJwogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSwgdGltZW91dCk7CiAgICAgIH0KCiAgICAgIC8vIOW/g+i3s+acuuWItgogICAgfSwgewogICAgICBrZXk6ICJzZXRQaW5nIiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldFBpbmcoKSB7CiAgICAgICAgdmFyIF90aGlzNSA9IHRoaXM7CiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ0ludGVydmFsVGltZXIpOwogICAgICAgIHRoaXMucGluZ0ludGVydmFsVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgIGlmIChfdGhpczUuZGVidWcpIGNvbnNvbGUubG9nKCclY1tzb2NrZXRdJywgJ2NvbG9yOiAjNDljOWM5OycsICdXUyBzZW5kIHBpbmcnKTsKICAgICAgICAgIF90aGlzNS5waW5nKCk7CiAgICAgICAgICBfdGhpczUub25IZWFydGJlYXQoX3RoaXM1LnBpbmdUaW1lb3V0KTsKICAgICAgICB9LCB0aGlzLnBpbmdJbnRlcnZhbCk7CiAgICAgIH0KICAgIH0sIHsKICAgICAga2V5OiAiYWRkRXZlbnRMaXN0ZW5lcnMiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcnMoKSB7CiAgICAgICAgdmFyIF90aGlzNiA9IHRoaXM7CiAgICAgICAgdmFyIGVuZ2luZSA9IHRoaXMuZW5naW5lOwogICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgICAgaWYgKGVuZ2luZSkgewogICAgICAgICAgZW5naW5lLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgX3RoaXM2Lm9uT3BlbigpOwogICAgICAgICAgfTsKICAgICAgICAgIGVuZ2luZS5vbmNsb3NlID0gZnVuY3Rpb24gKF9yZWYyKSB7CiAgICAgICAgICAgIHZhciBjb2RlID0gX3JlZjIuY29kZSwKICAgICAgICAgICAgICByZWFzb24gPSBfcmVmMi5yZWFzb247CiAgICAgICAgICAgIF90aGlzNi5vbkNsb3NlKHsKICAgICAgICAgICAgICBjb2RlOiBjb2RlLAogICAgICAgICAgICAgIHJlYXNvbjogcmVhc29uCiAgICAgICAgICAgIH0pOwogICAgICAgICAgfTsKICAgICAgICAgIGVuZ2luZS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZXYpIHsKICAgICAgICAgICAgaWYgKCgwLCBfdHlwZW9mMi5kZWZhdWx0KShldi5kYXRhKSA9PT0gJ29iamVjdCcpIHsKICAgICAgICAgICAgICB2YXIgdWludDggPSBuZXcgVWludDhBcnJheShldi5kYXRhKTsKICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gSlNPTi5wYXJzZSgoMCwgX3Bha28udW5nemlwKSh1aW50OCwgewogICAgICAgICAgICAgICAgdG86ICdzdHJpbmcnCiAgICAgICAgICAgICAgfSkpIHx8IHt9OwogICAgICAgICAgICAgIHJlc3VsdC50aW1lc3RhbXBFNiA9IHJlc3VsdC50cyB8fCAnJzsKICAgICAgICAgICAgICBfdGhpczYub25EYXRhKHJlc3VsdCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXYuZGF0YSBpbnN0YW5jZW9mIEJsb2IpIHsKICAgICAgICAgICAgICB2YXIgYmxvYiA9IGV2LmRhdGE7CiAgICAgICAgICAgICAgdmFyIF9yZXN1bHQgPSAnJzsKICAgICAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgICAgICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoYmxvYik7CiAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIF9yZXN1bHQgPSBKU09OLnBhcnNlKHBha28uaW5mbGF0ZShyZWFkZXIucmVzdWx0LCB7CiAgICAgICAgICAgICAgICAgIHRvOiAnc3RyaW5nJwogICAgICAgICAgICAgICAgfSkpOwogICAgICAgICAgICAgICAgLy/miZPljbDlh7rov5Tlm57nmoTmlbDmja4KICAgICAgICAgICAgICAgIF9yZXN1bHQudGltZXN0YW1wRTYgPSBfcmVzdWx0LnRzOwogICAgICAgICAgICAgICAgX3RoaXMub25EYXRhKF9yZXN1bHQpOwogICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgdmFyIGRhdGEgPSBKU09OLnBhcnNlKGV2LmRhdGEpOwogICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7CiAgICAgICAgICAgICAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChpKSB7CiAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIF90aGlzNi5vbkRhdGEoZGF0YVtpXSk7CiAgICAgICAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBkYXRhLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7CiAgICAgICAgICAgICAgICAgIF9sb29wKGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBfdGhpczYub25EYXRhKGRhdGEpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gZW5naW5lLnJlbW92ZUxpc3RlbmVyKCdvbm1lc3NhZ2UnKTsKICAgICAgICAgIH07CiAgICAgICAgICBlbmdpbmUub25lcnJvciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgX3RoaXM2Lm9uRXJyb3IoewogICAgICAgICAgICAgIGNvZGU6IDQ5OTksCiAgICAgICAgICAgICAgcmVhc29uOiAnb25lcnJvcicKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9OwogICAgICAgICAgZW5naW5lLm9uY2UoJ29wZW5fdGltZW91dCcsIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgIF90aGlzNi5vbkVycm9yKGUpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyDph43nva53ZWJzb2NrZXTlm57osIPlh73mlbAKICAgIH0sIHsKICAgICAga2V5OiAiY2xlYXJVcCIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGVhclVwKCkgewogICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnd3MtLT5jbGVhclVwJyk7CiAgICAgICAgdmFyIGVuZ2luZSA9IHRoaXMuZW5naW5lOwogICAgICAgIGVuZ2luZS5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7fTsKICAgICAgICBlbmdpbmUub25jbG9zZSA9IGZ1bmN0aW9uICgpIHt9OwogICAgICAgIGVuZ2luZS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoKSB7fTsKICAgICAgICBlbmdpbmUub25lcnJvciA9IGZ1bmN0aW9uICgpIHt9OwogICAgICAgIHRoaXMuY2xlYXJFVigpOwogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogImNsZWFyRVYiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gY2xlYXJFVigpIHsKICAgICAgICB2YXIgZXZMZW5ndGggPSB0aGlzLmV2Lmxlbmd0aDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV2TGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgIHZhciBzdWIgPSB0aGlzLmV2LnNoaWZ0KCk7CiAgICAgICAgICBzdWIuZGVzdHJveSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKiBlc2xpbnQtZGlzYWJsZSAqLwogICAgICAvLyAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlcnNjb3JlLWRhbmdsZSAqLwogICAgfSwgewogICAgICBrZXk6ICJyZWNvbm5lY3Rpb25BdHRlbXB0cyIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWNvbm5lY3Rpb25BdHRlbXB0cyh2KSB7CiAgICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uQXR0ZW1wdHM7CiAgICAgICAgdGhpcy5fcmVjb25uZWN0aW9uQXR0ZW1wdHMgPSB2OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogInJlY29ubmVjdGlvbkRlbGF5IiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlY29ubmVjdGlvbkRlbGF5KHYpIHsKICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheTsKICAgICAgICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheSA9IHY7CiAgICAgICAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRNaW4odik7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgIH0sIHsKICAgICAga2V5OiAicmVjb25uZWN0aW9uRGVsYXlNYXgiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gcmVjb25uZWN0aW9uRGVsYXlNYXgodikgewogICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5TWF4OwogICAgICAgIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5TWF4ID0gdjsKICAgICAgICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldE1heCh2KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgfSwgewogICAgICBrZXk6ICJyYW5kb21pemF0aW9uRmFjdG9yIiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJhbmRvbWl6YXRpb25GYWN0b3IodikgewogICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3I7CiAgICAgICAgdGhpcy5fcmFuZG9taXphdGlvbkZhY3RvciA9IHY7CiAgICAgICAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRKaXR0ZXIodik7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgIH0sIHsKICAgICAga2V5OiAidGltZW91dCIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiB0aW1lb3V0KHYpIHsKICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl90aW1lb3V0OwogICAgICAgIHRoaXMuX3RpbWVvdXQgPSB2OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICB9XSk7CiAgfSgpOwogICgwLCBfY29tcG9uZW50RW1pdHRlci5kZWZhdWx0KShXUy5wcm90b3R5cGUpOwogIGRlZmF1bHRfMSA9IGxpYi5kZWZhdWx0ID0gV1M7CgogIHZhciBFYXN5V1MgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9XUykgewogICAgZnVuY3Rpb24gRWFzeVdTKHVyaSwgb3B0cykgewogICAgICB2YXIgX3RoaXM7CiAgICAgIF9jbGFzc0NhbGxDaGVjayQxKHRoaXMsIEVhc3lXUyk7CiAgICAgIF90aGlzID0gX2NhbGxTdXBlcih0aGlzLCBFYXN5V1MsIFt1cmksIG9wdHNdKTsKICAgICAgX3RoaXMuY2hhbm5lbHMgPSB7fTsKICAgICAgX3RoaXMuX3RvQ2hhbm5lbHMgPSB7fTsKICAgICAgX3RoaXMuc29ja2V0SWQgPSAnJzsKICAgICAgX3RoaXMuY29uZmlnTGlzdGVuZXJzKCk7CiAgICAgIHJldHVybiBfdGhpczsKICAgIH0KICAgIF9pbmhlcml0cyhFYXN5V1MsIF9XUyk7CiAgICByZXR1cm4gX2NyZWF0ZUNsYXNzJDEoRWFzeVdTLCBbewogICAgICBrZXk6ICJjb25maWdMaXN0ZW5lcnMiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gY29uZmlnTGlzdGVuZXJzKCkgewogICAgICAgIHZhciBfdGhpczIgPSB0aGlzOwogICAgICAgIHZhciBzdWJzQWxsQ2hhbm5lbHMgPSBmdW5jdGlvbiBzdWJzQWxsQ2hhbm5lbHMoKSB7CiAgICAgICAgICAvLyBjb25zdCB3c290ID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSB0aGlzLm9wZW5TdGFydDsKICAgICAgICAgIC8vIOWPkemAgeiuoumYheWFrOeUqGNoYW5uZWwKICAgICAgICAgIHZhciBwYktleXMgPSBPYmplY3Qua2V5cyhfdGhpczIuY2hhbm5lbHMpOwogICAgICAgICAgaWYgKHBiS2V5cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIF90aGlzMi5zdWJzY3JpYmUocGJLZXlzKTsKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHZhciBzdWJzVG9DaGFubmVscyA9IGZ1bmN0aW9uIHN1YnNUb0NoYW5uZWxzKCkgewogICAgICAgICAgLy8gY29uc3Qgd3NmY3QgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuY29ubmVjdFN0YXJ0OwogICAgICAgICAgLy8g5Y+R6YCB6K6i6ZiF5YWs55SoY2hhbm5lbAogICAgICAgICAgdmFyIHBiS2V5cyA9IE9iamVjdC5rZXlzKF90aGlzMi5fdG9DaGFubmVscyk7CiAgICAgICAgICBpZiAocGJLZXlzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgX3RoaXMyLnN1YnNjcmliZShwYktleXMpOwogICAgICAgICAgICBfdGhpczIuX3RvQ2hhbm5lbHMgPSB7fTsKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHRoaXMub24oJ2Nvbm5lY3QnLCBzdWJzVG9DaGFubmVscyk7CiAgICAgICAgdGhpcy5vbigncmVjb25uZWN0Jywgc3Vic0FsbENoYW5uZWxzKTsKICAgICAgICB0aGlzLm9uKCdjbG9zZScsIGZ1bmN0aW9uIChfcmVmKSB7CiAgICAgICAgICB2YXIgY29kZSA9IF9yZWYuY29kZTsKICAgICAgICAgICAgX3JlZi5yZWFzb247CiAgICAgICAgICBpZiAoY29kZSA9PT0gMTAwMCkgewogICAgICAgICAgICBfdGhpczIuY2hhbm5lbHMgPSB7fTsKICAgICAgICAgICAgX3RoaXMyLl90b0NoYW5uZWxzID0ge307CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgdGhpcy5vbignc3Vic2NyaWJlX3N1Y2Nlc3MnLCBmdW5jdGlvbiAoc29ja2V0SWQpIHsKICAgICAgICAgIF90aGlzMi5zb2NrZXRJZCA9IHNvY2tldElkOwogICAgICAgIH0pOwogICAgICAgIHRoaXMub24oJ3N1YnNjcmliZV9mYWlsJywgZnVuY3Rpb24gKHNvY2tldElkKSB7CiAgICAgICAgICBfdGhpczIuc29ja2V0SWQgPSBzb2NrZXRJZDsKICAgICAgICB9KTsKICAgICAgfQogICAgfSwgewogICAgICBrZXk6ICJzdWJzY3JpYmUiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gc3Vic2NyaWJlKCkgewogICAgICAgIHZhciBzdWJzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBbXTsKICAgICAgICB0aGlzLnNlbmQoewogICAgICAgICAgb3A6ICdzdWJzY3JpYmUnLAogICAgICAgICAgYXJnczogc3VicwogICAgICAgIH0pOwogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogInVuc3Vic2NyaWJlIiwKICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVuc3Vic2NyaWJlKCkgewogICAgICAgIHZhciB1bnN1YnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFtdOwogICAgICAgIHRoaXMuc2VuZCh7CiAgICAgICAgICBvcDogJ3Vuc3Vic2NyaWJlJywKICAgICAgICAgIGFyZ3M6IHVuc3VicwogICAgICAgIH0pOwogICAgICB9CiAgICB9LCB7CiAgICAgIGtleTogImNoYW5uZWwiLAogICAgICB2YWx1ZTogZnVuY3Rpb24gY2hhbm5lbCh0b3BpYywgY2FsbGJhY2ssIGZvcmNlKSB7CiAgICAgICAgaWYgKHRoaXMucmVhZHlTdGF0ZSA9PT0gJ2Nsb3NlZF91c2VyJykgcmV0dXJuIG51bGw7CiAgICAgICAgdmFyIGhhcyA9IHRoaXMuY2hhbm5lbHNbdG9waWNdOwogICAgICAgIC8vIOWmguaenOW9k+WJjXRvcGlj5rKh5pyJ6K6i6ZiF5oiW6ICF6ZyA6KaB5by65Yi26K6i6ZiFCiAgICAgICAgaWYgKCFoYXMgfHwgZm9yY2UpIHsKICAgICAgICAgIHRoaXMuY2hhbm5lbHNbdG9waWNdID0gY2FsbGJhY2s7CiAgICAgICAgICB0aGlzLm9uKHRvcGljLCBjYWxsYmFjayk7CiAgICAgICAgICBpZiAodGhpcy5jb25uZWN0ZWQpIHsKICAgICAgICAgICAgaWYgKGhhcyAmJiBmb3JjZSkgewogICAgICAgICAgICAgIHRoaXMudW5zdWJzY3JpYmUoW3RvcGljXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5zdWJzY3JpYmUoW3RvcGljXSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLl90b0NoYW5uZWxzW3RvcGljXSA9IGNhbGxiYWNrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwgewogICAgICBrZXk6ICJsZWF2ZSIsCiAgICAgIHZhbHVlOiBmdW5jdGlvbiBsZWF2ZSh0b3BpYykgewogICAgICAgIGlmICh0aGlzLmNoYW5uZWxzW3RvcGljXSkgewogICAgICAgICAgdGhpcy5vZmYodG9waWMsIHRoaXMuY2hhbm5lbHNbdG9waWNdKTsKICAgICAgICAgIGRlbGV0ZSB0aGlzLmNoYW5uZWxzW3RvcGljXTsKICAgICAgICAgIGlmICh0aGlzLmNvbm5lY3RlZCkgewogICAgICAgICAgICB0aGlzLnVuc3Vic2NyaWJlKFt0b3BpY10pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3RvQ2hhbm5lbHNbdG9waWNdOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfV0pOwogIH0oZGVmYXVsdF8xKTsKCiAgLy8g5biC5Lu344CB5qCH6K6w5Lu3IHRvcGljIOaemuS4vgogIHZhciBNYXJrZXRUeXBlczsKICAoZnVuY3Rpb24gKE1hcmtldFR5cGVzKSB7CiAgICBNYXJrZXRUeXBlc1siTUFSS0VUX0NBTkRMRSJdID0gIm1rdGMiOwogICAgTWFya2V0VHlwZXNbIk1BUktfQ0FORExFIl0gPSAibXJrYyI7CiAgfSkoTWFya2V0VHlwZXMgfHwgKE1hcmtldFR5cGVzID0ge30pKTsKICAvLyDooYzmg4XmjqjpgIEgdG9waWMg5p6a5Li+CiAgLy8gSDogMTAwbXM7IE06IDEwMDBtcwogIHZhciBQdWJsaWNXc1RvcGljczsKICAoZnVuY3Rpb24gKFB1YmxpY1dzVG9waWNzKSB7CiAgICBQdWJsaWNXc1RvcGljc1siSW5kZXhRdW90ZTIwX0giXSA9ICJpbmRleF9xdW90ZV8yMC5ILiI7CiAgICBQdWJsaWNXc1RvcGljc1siSW5kZXhRdW90ZTIwMF9IIl0gPSAiaW5kZXhfcXVvdGVfMjAwLkguIjsKICAgIFB1YmxpY1dzVG9waWNzWyJJbnN0cnVtZW50SW5mb19IIl0gPSAiaW5zdHJ1bWVudF9pbmZvLkguIjsKICAgIFB1YmxpY1dzVG9waWNzWyJJbnN0cnVtZW50SW5mb19NIl0gPSAiaW5zdHJ1bWVudF9pbmZvLk0uIjsKICAgIFB1YmxpY1dzVG9waWNzWyJJbnN0cnVtZW50SW5mb0FsbCJdID0gImluc3RydW1lbnRfaW5mb192My5hbGwiOwogICAgUHVibGljV3NUb3BpY3NbIlB1YmxpY05vdGljZSJdID0gInB1YmxpYy5ub3RpY2UiOwogICAgUHVibGljV3NUb3BpY3NbIk9yZGVyQm9vayJdID0gIm9yZGVyQm9va18iOwogICAgUHVibGljV3NUb3BpY3NbIlJlY2VudFRyYWRlIl0gPSAicmVjZW50bHlfdHJhZGUuSC4iOwogICAgUHVibGljV3NUb3BpY3NbIlRpbWVDb2luU3ltYm9sTm90aWZ5Il0gPSAicHVibGljLnN5bWJvbC5ub3RpZnkiOwogICAgUHVibGljV3NUb3BpY3NbIk1UNVRpY2tlcnNBbGwiXSA9ICJtdDUudGlja2Vycy5hbGwiOwogICAgUHVibGljV3NUb3BpY3NbIk1UNUtsaW5lIl0gPSAibXQ1LmtsaW5lLiI7CiAgICBQdWJsaWNXc1RvcGljc1siTVQ1T3JkZXJCb29rIl0gPSAibXQ1Lm9iXyI7CiAgICBQdWJsaWNXc1RvcGljc1siQWxwaGFUaWNrZXJzQWxsIl0gPSAiYWxwaGEudGlja2VyLmFsbCI7CiAgfSkoUHVibGljV3NUb3BpY3MgfHwgKFB1YmxpY1dzVG9waWNzID0ge30pKTsKICB2YXIgT3JkZXJBY3Rpb247CiAgKGZ1bmN0aW9uIChPcmRlckFjdGlvbikgewogICAgT3JkZXJBY3Rpb25bIkJVWSJdID0gIkJ1eSI7CiAgICBPcmRlckFjdGlvblsiU0VMTCJdID0gIlNlbGwiOwogIH0pKE9yZGVyQWN0aW9uIHx8IChPcmRlckFjdGlvbiA9IHt9KSk7CiAgLy8gd3Mg5LqL5Lu25p6a5Li+CiAgdmFyIFdlYnNvY2tldEV2ZW50czsKICAoZnVuY3Rpb24gKFdlYnNvY2tldEV2ZW50cykgewogICAgV2Vic29ja2V0RXZlbnRzWyJDT05ORUNUIl0gPSAiY29ubmVjdCI7CiAgICBXZWJzb2NrZXRFdmVudHNbIkNPTk5FQ1RFRCJdID0gImNvbm5lY3RlZCI7CiAgICBXZWJzb2NrZXRFdmVudHNbIlJFQ09OTkVDVCJdID0gInJlY29ubmVjdCI7CiAgICBXZWJzb2NrZXRFdmVudHNbIkNMT1NFIl0gPSAiY2xvc2UiOwogICAgV2Vic29ja2V0RXZlbnRzWyJXU09UIl0gPSAiV1NPVCI7CiAgICBXZWJzb2NrZXRFdmVudHNbIldTRkNUIl0gPSAiV1NGQ1QiOwogICAgV2Vic29ja2V0RXZlbnRzWyJDTE9TRV9CWV9PVEhFUiJdID0gImNsb3NlX2J5X290aGVyIjsKICAgIFdlYnNvY2tldEV2ZW50c1siT1BFTl9FUlJPUiJdID0gIm9wZW5fZXJyb3IiOwogICAgV2Vic29ja2V0RXZlbnRzWyJIRUFSVF9FUlJPUiJdID0gImhlYXJ0X2Vycm9yIjsKICAgIFdlYnNvY2tldEV2ZW50c1siSEVBUlRfQkFDSyJdID0gImhlYXJ0X2JhY2siOwogICAgV2Vic29ja2V0RXZlbnRzWyJFUlJPUiJdID0gImVycm9yIjsKICAgIFdlYnNvY2tldEV2ZW50c1siUkVDT05ORUNUX0ZBSUxFRCJdID0gInJlY29ubmVjdF9mYWlsZWQiOwogICAgV2Vic29ja2V0RXZlbnRzWyJSRUNPTk5FQ1RfU1RBUlQiXSA9ICJyZWNvbm5lY3Rfc3RhcnQiOwogIH0pKFdlYnNvY2tldEV2ZW50cyB8fCAoV2Vic29ja2V0RXZlbnRzID0ge30pKTsKICB2YXIgUHVibGljRnNUb3BpY3M7CiAgKGZ1bmN0aW9uIChQdWJsaWNGc1RvcGljcykgewogICAgUHVibGljRnNUb3BpY3NbIk9yZGVyQm9vayJdID0gInNwcmVhZC5vcmRlckJvb2tfIjsKICAgIFB1YmxpY0ZzVG9waWNzWyJJbnN0cnVtZW50SW5mbyJdID0gInNwcmVhZC5pbnN0cnVtZW50X2luZm8uIjsKICAgIFB1YmxpY0ZzVG9waWNzWyJJbnN0cnVtZW50SW5mb0FsbCJdID0gInNwcmVhZC5pbnN0cnVtZW50X2luZm8uYWxsIjsKICAgIFB1YmxpY0ZzVG9waWNzWyJSZWNlbnRUcmFkZSJdID0gInNwcmVhZC5yZWNlbnRfdHJhZGVzLiI7CiAgfSkoUHVibGljRnNUb3BpY3MgfHwgKFB1YmxpY0ZzVG9waWNzID0ge30pKTsKICB2YXIgUHVibGljT3B0aW9uRXZlbnRzOwogIChmdW5jdGlvbiAoUHVibGljT3B0aW9uRXZlbnRzKSB7CiAgICBQdWJsaWNPcHRpb25FdmVudHNbIk9yZGVyQm9vayJdID0gIm9iXyI7CiAgfSkoUHVibGljT3B0aW9uRXZlbnRzIHx8IChQdWJsaWNPcHRpb25FdmVudHMgPSB7fSkpOwoKICAvKiENCiAgICogIGRlY2ltYWwuanMgdjEwLjYuMA0KICAgKiAgQW4gYXJiaXRyYXJ5LXByZWNpc2lvbiBEZWNpbWFsIHR5cGUgZm9yIEphdmFTY3JpcHQuDQogICAqICBodHRwczovL2dpdGh1Yi5jb20vTWlrZU1jbC9kZWNpbWFsLmpzDQogICAqICBDb3B5cmlnaHQgKGMpIDIwMjUgTWljaGFlbCBNY2xhdWdobGluIDxNOGNoODhsQGdtYWlsLmNvbT4NCiAgICogIE1JVCBMaWNlbmNlDQogICAqLw0KDQoNCiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIEVESVRBQkxFIERFRkFVTFRTICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy8NCg0KDQogICAgLy8gVGhlIG1heGltdW0gZXhwb25lbnQgbWFnbml0dWRlLg0KICAgIC8vIFRoZSBsaW1pdCBvbiB0aGUgdmFsdWUgb2YgYHRvRXhwTmVnYCwgYHRvRXhwUG9zYCwgYG1pbkVgIGFuZCBgbWF4RWAuDQogIHZhciBFWFBfTElNSVQgPSA5ZTE1LCAgICAgICAgICAgICAgICAgICAgICAvLyAwIHRvIDllMTUNCg0KICAgIC8vIFRoZSBsaW1pdCBvbiB0aGUgdmFsdWUgb2YgYHByZWNpc2lvbmAsIGFuZCBvbiB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IGFyZ3VtZW50IHRvDQogICAgLy8gYHRvRGVjaW1hbFBsYWNlc2AsIGB0b0V4cG9uZW50aWFsYCwgYHRvRml4ZWRgLCBgdG9QcmVjaXNpb25gIGFuZCBgdG9TaWduaWZpY2FudERpZ2l0c2AuDQogICAgTUFYX0RJR0lUUyA9IDFlOSwgICAgICAgICAgICAgICAgICAgICAgICAvLyAwIHRvIDFlOQ0KDQogICAgLy8gQmFzZSBjb252ZXJzaW9uIGFscGhhYmV0Lg0KICAgIE5VTUVSQUxTID0gJzAxMjM0NTY3ODlhYmNkZWYnLA0KDQogICAgLy8gVGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIDEwICgxMDI1IGRpZ2l0cykuDQogICAgTE4xMCA9ICcyLjMwMjU4NTA5Mjk5NDA0NTY4NDAxNzk5MTQ1NDY4NDM2NDIwNzYwMTEwMTQ4ODYyODc3Mjk3NjAzMzMyNzkwMDk2NzU3MjYwOTY3NzM1MjQ4MDIzNTk5NzIwNTA4OTU5ODI5ODM0MTk2Nzc4NDA0MjI4NjI0ODYzMzQwOTUyNTQ2NTA4MjgwNjc1NjY2NjI4NzM2OTA5ODc4MTY4OTQ4MjkwNzIwODMyNTU1NDY4MDg0Mzc5OTg5NDgyNjIzMzE5ODUyODM5MzUwNTMwODk2NTM3NzczMjYyODg0NjE2MzM2NjIyMjI4NzY5ODIxOTg4Njc0NjU0MzY2NzQ3NDQwNDI0MzI3NDM2NTE1NTA0ODkzNDMxNDkzOTM5MTQ3OTYxOTQwNDQwMDIyMjEwNTEwMTcxNDE3NDgwMDM2ODgwODQwMTI2NDcwODA2ODU1Njc3NDMyMTYyMjgzNTUyMjAxMTQ4MDQ2NjM3MTU2NTkxMjEzNzM0NTA3NDc4NTY5NDc2ODM0NjM2MTY3OTIxMDE4MDY0NDUwNzA2NDgwMDAyNzc1MDI2ODQ5MTY3NDY1NTA1ODY4NTY5MzU2NzM0MjA2NzA1ODExMzY0MjkyMjQ1NTQ0MDU3NTg5MjU3MjQyMDgyNDEzMTQ2OTU2ODkwMTY3NTg5NDAyNTY3NzYzMTEzNTY5MTkyOTIwMzMzNzY1ODcxNDE2NjAyMzAxMDU3MDMwODk2MzQ1NzIwNzU0NDAzNzA4NDc0Njk5NDAxNjgyNjkyODI4MDg0ODExODQyODkzMTQ4NDg1MjQ5NDg2NDQ4NzE5Mjc4MDk2NzYyNzEyNzU3NzUzOTcwMjc2Njg2MDU5NTI0OTY3MTY2NzQxODM0ODU3MDQ0MjI1MDcxOTc5NjUwMDQ3MTQ5NTEwNTA0OTIyMTQ3NzY1Njc2MzY5Mzg2NjI5NzY5Nzk1MjIxMTA3MTgyNjQ1NDk3MzQ3NzI2NjI0MjU3MDk0MjkzMjI1ODI3OTg1MDI1ODU1MDk3ODUyNjUzODMyMDc2MDY3MjYzMTcxNjQzMDk1MDU5OTUwODc4MDc1MjM3MTAzMzMxMDExOTc4NTc1NDczMzE1NDE0MjE4MDg0Mjc1NDM4NjM1OTE3NzgxMTcwNTQzMDk4Mjc0ODIzODUwNDU2NDgwMTkwOTU2MTAyOTkyOTE4MjQzMTgyMzc1MjUzNTc3MDk3NTA1Mzk1NjUxODc2OTc1MTAzNzQ5NzA4ODg2OTIxODAyMDUxODkzMzk1MDcyMzg1MzkyMDUxNDQ2MzQxOTcyNjUyODcyODY5NjUxMTA4NjI1NzE0OTIxOTg4NDk5Nzg3NDg4NzM3NzEzNDU2ODYyMDkxNjcwNTgnLA0KDQogICAgLy8gUGkgKDEwMjUgZGlnaXRzKS4NCiAgICBQSSA9ICczLjE0MTU5MjY1MzU4OTc5MzIzODQ2MjY0MzM4MzI3OTUwMjg4NDE5NzE2OTM5OTM3NTEwNTgyMDk3NDk0NDU5MjMwNzgxNjQwNjI4NjIwODk5ODYyODAzNDgyNTM0MjExNzA2Nzk4MjE0ODA4NjUxMzI4MjMwNjY0NzA5Mzg0NDYwOTU1MDU4MjIzMTcyNTM1OTQwODEyODQ4MTExNzQ1MDI4NDEwMjcwMTkzODUyMTEwNTU1OTY0NDYyMjk0ODk1NDkzMDM4MTk2NDQyODgxMDk3NTY2NTkzMzQ0NjEyODQ3NTY0ODIzMzc4Njc4MzE2NTI3MTIwMTkwOTE0NTY0ODU2NjkyMzQ2MDM0ODYxMDQ1NDMyNjY0ODIxMzM5MzYwNzI2MDI0OTE0MTI3MzcyNDU4NzAwNjYwNjMxNTU4ODE3NDg4MTUyMDkyMDk2MjgyOTI1NDA5MTcxNTM2NDM2Nzg5MjU5MDM2MDAxMTMzMDUzMDU0ODgyMDQ2NjUyMTM4NDE0Njk1MTk0MTUxMTYwOTQzMzA1NzI3MDM2NTc1OTU5MTk1MzA5MjE4NjExNzM4MTkzMjYxMTc5MzEwNTExODU0ODA3NDQ2MjM3OTk2Mjc0OTU2NzM1MTg4NTc1MjcyNDg5MTIyNzkzODE4MzAxMTk0OTEyOTgzMzY3MzM2MjQ0MDY1NjY0MzA4NjAyMTM5NDk0NjM5NTIyNDczNzE5MDcwMjE3OTg2MDk0MzcwMjc3MDUzOTIxNzE3NjI5MzE3Njc1MjM4NDY3NDgxODQ2NzY2OTQwNTEzMjAwMDU2ODEyNzE0NTI2MzU2MDgyNzc4NTc3MTM0Mjc1Nzc4OTYwOTE3MzYzNzE3ODcyMTQ2ODQ0MDkwMTIyNDk1MzQzMDE0NjU0OTU4NTM3MTA1MDc5MjI3OTY4OTI1ODkyMzU0MjAxOTk1NjExMjEyOTAyMTk2MDg2NDAzNDQxODE1OTgxMzYyOTc3NDc3MTMwOTk2MDUxODcwNzIxMTM0OTk5OTk5ODM3Mjk3ODA0OTk1MTA1OTczMTczMjgxNjA5NjMxODU5NTAyNDQ1OTQ1NTM0NjkwODMwMjY0MjUyMjMwODI1MzM0NDY4NTAzNTI2MTkzMTE4ODE3MTAxMDAwMzEzNzgzODc1Mjg4NjU4NzUzMzIwODM4MTQyMDYxNzE3NzY2OTE0NzMwMzU5ODI1MzQ5MDQyODc1NTQ2ODczMTE1OTU2Mjg2Mzg4MjM1Mzc4NzU5Mzc1MTk1Nzc4MTg1Nzc4MDUzMjE3MTIyNjgwNjYxMzAwMTkyNzg3NjYxMTE5NTkwOTIxNjQyMDE5ODkzODA5NTI1NzIwMTA2NTQ4NTg2MzI3ODknLA0KDQoNCiAgICAvLyBUaGUgaW5pdGlhbCBjb25maWd1cmF0aW9uIHByb3BlcnRpZXMgb2YgdGhlIERlY2ltYWwgY29uc3RydWN0b3IuDQogICAgREVGQVVMVFMgPSB7DQoNCiAgICAgIC8vIFRoZXNlIHZhbHVlcyBtdXN0IGJlIGludGVnZXJzIHdpdGhpbiB0aGUgc3RhdGVkIHJhbmdlcyAoaW5jbHVzaXZlKS4NCiAgICAgIC8vIE1vc3Qgb2YgdGhlc2UgdmFsdWVzIGNhbiBiZSBjaGFuZ2VkIGF0IHJ1bi10aW1lIHVzaW5nIHRoZSBgRGVjaW1hbC5jb25maWdgIG1ldGhvZC4NCg0KICAgICAgLy8gVGhlIG1heGltdW0gbnVtYmVyIG9mIHNpZ25pZmljYW50IGRpZ2l0cyBvZiB0aGUgcmVzdWx0IG9mIGEgY2FsY3VsYXRpb24gb3IgYmFzZSBjb252ZXJzaW9uLg0KICAgICAgLy8gRS5nLiBgRGVjaW1hbC5jb25maWcoeyBwcmVjaXNpb246IDIwIH0pO2ANCiAgICAgIHByZWNpc2lvbjogMjAsICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDEgdG8gTUFYX0RJR0lUUw0KDQogICAgICAvLyBUaGUgcm91bmRpbmcgbW9kZSB1c2VkIHdoZW4gcm91bmRpbmcgdG8gYHByZWNpc2lvbmAuDQogICAgICAvLw0KICAgICAgLy8gUk9VTkRfVVAgICAgICAgICAwIEF3YXkgZnJvbSB6ZXJvLg0KICAgICAgLy8gUk9VTkRfRE9XTiAgICAgICAxIFRvd2FyZHMgemVyby4NCiAgICAgIC8vIFJPVU5EX0NFSUwgICAgICAgMiBUb3dhcmRzICtJbmZpbml0eS4NCiAgICAgIC8vIFJPVU5EX0ZMT09SICAgICAgMyBUb3dhcmRzIC1JbmZpbml0eS4NCiAgICAgIC8vIFJPVU5EX0hBTEZfVVAgICAgNCBUb3dhcmRzIG5lYXJlc3QgbmVpZ2hib3VyLiBJZiBlcXVpZGlzdGFudCwgdXAuDQogICAgICAvLyBST1VORF9IQUxGX0RPV04gIDUgVG93YXJkcyBuZWFyZXN0IG5laWdoYm91ci4gSWYgZXF1aWRpc3RhbnQsIGRvd24uDQogICAgICAvLyBST1VORF9IQUxGX0VWRU4gIDYgVG93YXJkcyBuZWFyZXN0IG5laWdoYm91ci4gSWYgZXF1aWRpc3RhbnQsIHRvd2FyZHMgZXZlbiBuZWlnaGJvdXIuDQogICAgICAvLyBST1VORF9IQUxGX0NFSUwgIDcgVG93YXJkcyBuZWFyZXN0IG5laWdoYm91ci4gSWYgZXF1aWRpc3RhbnQsIHRvd2FyZHMgK0luZmluaXR5Lg0KICAgICAgLy8gUk9VTkRfSEFMRl9GTE9PUiA4IFRvd2FyZHMgbmVhcmVzdCBuZWlnaGJvdXIuIElmIGVxdWlkaXN0YW50LCB0b3dhcmRzIC1JbmZpbml0eS4NCiAgICAgIC8vDQogICAgICAvLyBFLmcuDQogICAgICAvLyBgRGVjaW1hbC5yb3VuZGluZyA9IDQ7YA0KICAgICAgLy8gYERlY2ltYWwucm91bmRpbmcgPSBEZWNpbWFsLlJPVU5EX0hBTEZfVVA7YA0KICAgICAgcm91bmRpbmc6IDQsICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMCB0byA4DQoNCiAgICAgIC8vIFRoZSBtb2R1bG8gbW9kZSB1c2VkIHdoZW4gY2FsY3VsYXRpbmcgdGhlIG1vZHVsdXM6IGEgbW9kIG4uDQogICAgICAvLyBUaGUgcXVvdGllbnQgKHEgPSBhIC8gbikgaXMgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG8gdGhlIGNvcnJlc3BvbmRpbmcgcm91bmRpbmcgbW9kZS4NCiAgICAgIC8vIFRoZSByZW1haW5kZXIgKHIpIGlzIGNhbGN1bGF0ZWQgYXM6IHIgPSBhIC0gbiAqIHEuDQogICAgICAvLw0KICAgICAgLy8gVVAgICAgICAgICAwIFRoZSByZW1haW5kZXIgaXMgcG9zaXRpdmUgaWYgdGhlIGRpdmlkZW5kIGlzIG5lZ2F0aXZlLCBlbHNlIGlzIG5lZ2F0aXZlLg0KICAgICAgLy8gRE9XTiAgICAgICAxIFRoZSByZW1haW5kZXIgaGFzIHRoZSBzYW1lIHNpZ24gYXMgdGhlIGRpdmlkZW5kIChKYXZhU2NyaXB0ICUpLg0KICAgICAgLy8gRkxPT1IgICAgICAzIFRoZSByZW1haW5kZXIgaGFzIHRoZSBzYW1lIHNpZ24gYXMgdGhlIGRpdmlzb3IgKFB5dGhvbiAlKS4NCiAgICAgIC8vIEhBTEZfRVZFTiAgNiBUaGUgSUVFRSA3NTQgcmVtYWluZGVyIGZ1bmN0aW9uLg0KICAgICAgLy8gRVVDTElEICAgICA5IEV1Y2xpZGlhbiBkaXZpc2lvbi4gcSA9IHNpZ24obikgKiBmbG9vcihhIC8gYWJzKG4pKS4gQWx3YXlzIHBvc2l0aXZlLg0KICAgICAgLy8NCiAgICAgIC8vIFRydW5jYXRlZCBkaXZpc2lvbiAoMSksIGZsb29yZWQgZGl2aXNpb24gKDMpLCB0aGUgSUVFRSA3NTQgcmVtYWluZGVyICg2KSwgYW5kIEV1Y2xpZGlhbg0KICAgICAgLy8gZGl2aXNpb24gKDkpIGFyZSBjb21tb25seSB1c2VkIGZvciB0aGUgbW9kdWx1cyBvcGVyYXRpb24uIFRoZSBvdGhlciByb3VuZGluZyBtb2RlcyBjYW4gYWxzbw0KICAgICAgLy8gYmUgdXNlZCwgYnV0IHRoZXkgbWF5IG5vdCBnaXZlIHVzZWZ1bCByZXN1bHRzLg0KICAgICAgbW9kdWxvOiAxLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMCB0byA5DQoNCiAgICAgIC8vIFRoZSBleHBvbmVudCB2YWx1ZSBhdCBhbmQgYmVuZWF0aCB3aGljaCBgdG9TdHJpbmdgIHJldHVybnMgZXhwb25lbnRpYWwgbm90YXRpb24uDQogICAgICAvLyBKYXZhU2NyaXB0IG51bWJlcnM6IC03DQogICAgICB0b0V4cE5lZzogLTcsICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAwIHRvIC1FWFBfTElNSVQNCg0KICAgICAgLy8gVGhlIGV4cG9uZW50IHZhbHVlIGF0IGFuZCBhYm92ZSB3aGljaCBgdG9TdHJpbmdgIHJldHVybnMgZXhwb25lbnRpYWwgbm90YXRpb24uDQogICAgICAvLyBKYXZhU2NyaXB0IG51bWJlcnM6IDIxDQogICAgICB0b0V4cFBvczogIDIxLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyAwIHRvIEVYUF9MSU1JVA0KDQogICAgICAvLyBUaGUgbWluaW11bSBleHBvbmVudCB2YWx1ZSwgYmVuZWF0aCB3aGljaCB1bmRlcmZsb3cgdG8gemVybyBvY2N1cnMuDQogICAgICAvLyBKYXZhU2NyaXB0IG51bWJlcnM6IC0zMjQgICg1ZS0zMjQpDQogICAgICBtaW5FOiAtRVhQX0xJTUlULCAgICAgICAgICAgICAgICAgICAgICAvLyAtMSB0byAtRVhQX0xJTUlUDQoNCiAgICAgIC8vIFRoZSBtYXhpbXVtIGV4cG9uZW50IHZhbHVlLCBhYm92ZSB3aGljaCBvdmVyZmxvdyB0byBJbmZpbml0eSBvY2N1cnMuDQogICAgICAvLyBKYXZhU2NyaXB0IG51bWJlcnM6IDMwOCAgKDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4KQ0KICAgICAgbWF4RTogRVhQX0xJTUlULCAgICAgICAgICAgICAgICAgICAgICAgLy8gMSB0byBFWFBfTElNSVQNCg0KICAgICAgLy8gV2hldGhlciB0byB1c2UgY3J5cHRvZ3JhcGhpY2FsbHktc2VjdXJlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdGlvbiwgaWYgYXZhaWxhYmxlLg0KICAgICAgY3J5cHRvOiBmYWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJ1ZS9mYWxzZQ0KICAgIH0sDQoNCg0KICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFTkQgT0YgRURJVEFCTEUgREVGQVVMVFMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvLw0KDQoNCiAgICBpbmV4YWN0LCBxdWFkcmFudCwNCiAgICBleHRlcm5hbCA9IHRydWUsDQoNCiAgICBkZWNpbWFsRXJyb3IgPSAnW0RlY2ltYWxFcnJvcl0gJywNCiAgICBpbnZhbGlkQXJndW1lbnQgPSBkZWNpbWFsRXJyb3IgKyAnSW52YWxpZCBhcmd1bWVudDogJywNCiAgICBwcmVjaXNpb25MaW1pdEV4Y2VlZGVkID0gZGVjaW1hbEVycm9yICsgJ1ByZWNpc2lvbiBsaW1pdCBleGNlZWRlZCcsDQogICAgY3J5cHRvVW5hdmFpbGFibGUgPSBkZWNpbWFsRXJyb3IgKyAnY3J5cHRvIHVuYXZhaWxhYmxlJywNCiAgICB0YWcgPSAnW29iamVjdCBEZWNpbWFsXScsDQoNCiAgICBtYXRoZmxvb3IgPSBNYXRoLmZsb29yLA0KICAgIG1hdGhwb3cgPSBNYXRoLnBvdywNCg0KICAgIGlzQmluYXJ5ID0gL14wYihbMDFdKyhcLlswMV0qKT98XC5bMDFdKykocFsrLV0/XGQrKT8kL2ksDQogICAgaXNIZXggPSAvXjB4KFswLTlhLWZdKyhcLlswLTlhLWZdKik/fFwuWzAtOWEtZl0rKShwWystXT9cZCspPyQvaSwNCiAgICBpc09jdGFsID0gL14wbyhbMC03XSsoXC5bMC03XSopP3xcLlswLTddKykocFsrLV0/XGQrKT8kL2ksDQogICAgaXNEZWNpbWFsID0gL14oXGQrKFwuXGQqKT98XC5cZCspKGVbKy1dP1xkKyk/JC9pLA0KDQogICAgQkFTRSA9IDFlNywNCiAgICBMT0dfQkFTRSA9IDcsDQogICAgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTEsDQoNCiAgICBMTjEwX1BSRUNJU0lPTiA9IExOMTAubGVuZ3RoIC0gMSwNCiAgICBQSV9QUkVDSVNJT04gPSBQSS5sZW5ndGggLSAxLA0KDQogICAgLy8gRGVjaW1hbC5wcm90b3R5cGUgb2JqZWN0DQogICAgUCA9IHsgdG9TdHJpbmdUYWc6IHRhZyB9Ow0KDQoNCiAgLy8gRGVjaW1hbCBwcm90b3R5cGUgbWV0aG9kcw0KDQoNCiAgLyoNCiAgICogIGFic29sdXRlVmFsdWUgICAgICAgICAgICAgYWJzDQogICAqICBjZWlsDQogICAqICBjbGFtcGVkVG8gICAgICAgICAgICAgICAgIGNsYW1wDQogICAqICBjb21wYXJlZFRvICAgICAgICAgICAgICAgIGNtcA0KICAgKiAgY29zaW5lICAgICAgICAgICAgICAgICAgICBjb3MNCiAgICogIGN1YmVSb290ICAgICAgICAgICAgICAgICAgY2JydA0KICAgKiAgZGVjaW1hbFBsYWNlcyAgICAgICAgICAgICBkcA0KICAgKiAgZGl2aWRlZEJ5ICAgICAgICAgICAgICAgICBkaXYNCiAgICogIGRpdmlkZWRUb0ludGVnZXJCeSAgICAgICAgZGl2VG9JbnQNCiAgICogIGVxdWFscyAgICAgICAgICAgICAgICAgICAgZXENCiAgICogIGZsb29yDQogICAqICBncmVhdGVyVGhhbiAgICAgICAgICAgICAgIGd0DQogICAqICBncmVhdGVyVGhhbk9yRXF1YWxUbyAgICAgIGd0ZQ0KICAgKiAgaHlwZXJib2xpY0Nvc2luZSAgICAgICAgICBjb3NoDQogICAqICBoeXBlcmJvbGljU2luZSAgICAgICAgICAgIHNpbmgNCiAgICogIGh5cGVyYm9saWNUYW5nZW50ICAgICAgICAgdGFuaA0KICAgKiAgaW52ZXJzZUNvc2luZSAgICAgICAgICAgICBhY29zDQogICAqICBpbnZlcnNlSHlwZXJib2xpY0Nvc2luZSAgIGFjb3NoDQogICAqICBpbnZlcnNlSHlwZXJib2xpY1NpbmUgICAgIGFzaW5oDQogICAqICBpbnZlcnNlSHlwZXJib2xpY1RhbmdlbnQgIGF0YW5oDQogICAqICBpbnZlcnNlU2luZSAgICAgICAgICAgICAgIGFzaW4NCiAgICogIGludmVyc2VUYW5nZW50ICAgICAgICAgICAgYXRhbg0KICAgKiAgaXNGaW5pdGUNCiAgICogIGlzSW50ZWdlciAgICAgICAgICAgICAgICAgaXNJbnQNCiAgICogIGlzTmFODQogICAqICBpc05lZ2F0aXZlICAgICAgICAgICAgICAgIGlzTmVnDQogICAqICBpc1Bvc2l0aXZlICAgICAgICAgICAgICAgIGlzUG9zDQogICAqICBpc1plcm8NCiAgICogIGxlc3NUaGFuICAgICAgICAgICAgICAgICAgbHQNCiAgICogIGxlc3NUaGFuT3JFcXVhbFRvICAgICAgICAgbHRlDQogICAqICBsb2dhcml0aG0gICAgICAgICAgICAgICAgIGxvZw0KICAgKiAgW21heGltdW1dICAgICAgICAgICAgICAgICBbbWF4XQ0KICAgKiAgW21pbmltdW1dICAgICAgICAgICAgICAgICBbbWluXQ0KICAgKiAgbWludXMgICAgICAgICAgICAgICAgICAgICBzdWINCiAgICogIG1vZHVsbyAgICAgICAgICAgICAgICAgICAgbW9kDQogICAqICBuYXR1cmFsRXhwb25lbnRpYWwgICAgICAgIGV4cA0KICAgKiAgbmF0dXJhbExvZ2FyaXRobSAgICAgICAgICBsbg0KICAgKiAgbmVnYXRlZCAgICAgICAgICAgICAgICAgICBuZWcNCiAgICogIHBsdXMgICAgICAgICAgICAgICAgICAgICAgYWRkDQogICAqICBwcmVjaXNpb24gICAgICAgICAgICAgICAgIHNkDQogICAqICByb3VuZA0KICAgKiAgc2luZSAgICAgICAgICAgICAgICAgICAgICBzaW4NCiAgICogIHNxdWFyZVJvb3QgICAgICAgICAgICAgICAgc3FydA0KICAgKiAgdGFuZ2VudCAgICAgICAgICAgICAgICAgICB0YW4NCiAgICogIHRpbWVzICAgICAgICAgICAgICAgICAgICAgbXVsDQogICAqICB0b0JpbmFyeQ0KICAgKiAgdG9EZWNpbWFsUGxhY2VzICAgICAgICAgICB0b0RQDQogICAqICB0b0V4cG9uZW50aWFsDQogICAqICB0b0ZpeGVkDQogICAqICB0b0ZyYWN0aW9uDQogICAqICB0b0hleGFkZWNpbWFsICAgICAgICAgICAgIHRvSGV4DQogICAqICB0b05lYXJlc3QNCiAgICogIHRvTnVtYmVyDQogICAqICB0b09jdGFsDQogICAqICB0b1Bvd2VyICAgICAgICAgICAgICAgICAgIHBvdw0KICAgKiAgdG9QcmVjaXNpb24NCiAgICogIHRvU2lnbmlmaWNhbnREaWdpdHMgICAgICAgdG9TRA0KICAgKiAgdG9TdHJpbmcNCiAgICogIHRydW5jYXRlZCAgICAgICAgICAgICAgICAgdHJ1bmMNCiAgICogIHZhbHVlT2YgICAgICAgICAgICAgICAgICAgdG9KU09ODQogICAqLw0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbC4NCiAgICoNCiAgICovDQogIFAuYWJzb2x1dGVWYWx1ZSA9IFAuYWJzID0gZnVuY3Rpb24gKCkgew0KICAgIHZhciB4ID0gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcyk7DQogICAgaWYgKHgucyA8IDApIHgucyA9IDE7DQogICAgcmV0dXJuIGZpbmFsaXNlKHgpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCByb3VuZGVkIHRvIGEgd2hvbGUgbnVtYmVyIGluIHRoZQ0KICAgKiBkaXJlY3Rpb24gb2YgcG9zaXRpdmUgSW5maW5pdHkuDQogICAqDQogICAqLw0KICBQLmNlaWwgPSBmdW5jdGlvbiAoKSB7DQogICAgcmV0dXJuIGZpbmFsaXNlKG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMpLCB0aGlzLmUgKyAxLCAyKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgY2xhbXBlZCB0byB0aGUgcmFuZ2UNCiAgICogZGVsaW5lYXRlZCBieSBgbWluYCBhbmQgYG1heGAuDQogICAqDQogICAqIG1pbiB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICogbWF4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgUC5jbGFtcGVkVG8gPSBQLmNsYW1wID0gZnVuY3Rpb24gKG1pbiwgbWF4KSB7DQogICAgdmFyIGssDQogICAgICB4ID0gdGhpcywNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yOw0KICAgIG1pbiA9IG5ldyBDdG9yKG1pbik7DQogICAgbWF4ID0gbmV3IEN0b3IobWF4KTsNCiAgICBpZiAoIW1pbi5zIHx8ICFtYXgucykgcmV0dXJuIG5ldyBDdG9yKE5hTik7DQogICAgaWYgKG1pbi5ndChtYXgpKSB0aHJvdyBFcnJvcihpbnZhbGlkQXJndW1lbnQgKyBtYXgpOw0KICAgIGsgPSB4LmNtcChtaW4pOw0KICAgIHJldHVybiBrIDwgMCA/IG1pbiA6IHguY21wKG1heCkgPiAwID8gbWF4IDogbmV3IEN0b3IoeCk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4NCiAgICogICAxICAgIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiBgeWAsDQogICAqICAtMSAgICBpZiB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIGlzIGxlc3MgdGhhbiB0aGUgdmFsdWUgb2YgYHlgLA0KICAgKiAgIDAgICAgaWYgdGhleSBoYXZlIHRoZSBzYW1lIHZhbHVlLA0KICAgKiAgIE5hTiAgaWYgdGhlIHZhbHVlIG9mIGVpdGhlciBEZWNpbWFsIGlzIE5hTi4NCiAgICoNCiAgICovDQogIFAuY29tcGFyZWRUbyA9IFAuY21wID0gZnVuY3Rpb24gKHkpIHsNCiAgICB2YXIgaSwgaiwgeGRMLCB5ZEwsDQogICAgICB4ID0gdGhpcywNCiAgICAgIHhkID0geC5kLA0KICAgICAgeWQgPSAoeSA9IG5ldyB4LmNvbnN0cnVjdG9yKHkpKS5kLA0KICAgICAgeHMgPSB4LnMsDQogICAgICB5cyA9IHkuczsNCg0KICAgIC8vIEVpdGhlciBOYU4gb3IgwrFJbmZpbml0eT8NCiAgICBpZiAoIXhkIHx8ICF5ZCkgew0KICAgICAgcmV0dXJuICF4cyB8fCAheXMgPyBOYU4gOiB4cyAhPT0geXMgPyB4cyA6IHhkID09PSB5ZCA/IDAgOiAheGQgXiB4cyA8IDAgPyAxIDogLTE7DQogICAgfQ0KDQogICAgLy8gRWl0aGVyIHplcm8/DQogICAgaWYgKCF4ZFswXSB8fCAheWRbMF0pIHJldHVybiB4ZFswXSA/IHhzIDogeWRbMF0gPyAteXMgOiAwOw0KDQogICAgLy8gU2lnbnMgZGlmZmVyPw0KICAgIGlmICh4cyAhPT0geXMpIHJldHVybiB4czsNCg0KICAgIC8vIENvbXBhcmUgZXhwb25lbnRzLg0KICAgIGlmICh4LmUgIT09IHkuZSkgcmV0dXJuIHguZSA+IHkuZSBeIHhzIDwgMCA/IDEgOiAtMTsNCg0KICAgIHhkTCA9IHhkLmxlbmd0aDsNCiAgICB5ZEwgPSB5ZC5sZW5ndGg7DQoNCiAgICAvLyBDb21wYXJlIGRpZ2l0IGJ5IGRpZ2l0Lg0KICAgIGZvciAoaSA9IDAsIGogPSB4ZEwgPCB5ZEwgPyB4ZEwgOiB5ZEw7IGkgPCBqOyArK2kpIHsNCiAgICAgIGlmICh4ZFtpXSAhPT0geWRbaV0pIHJldHVybiB4ZFtpXSA+IHlkW2ldIF4geHMgPCAwID8gMSA6IC0xOw0KICAgIH0NCg0KICAgIC8vIENvbXBhcmUgbGVuZ3Rocy4NCiAgICByZXR1cm4geGRMID09PSB5ZEwgPyAwIDogeGRMID4geWRMIF4geHMgPCAwID8gMSA6IC0xOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGNvc2luZSBvZiB0aGUgdmFsdWUgaW4gcmFkaWFucyBvZiB0aGlzIERlY2ltYWwuDQogICAqDQogICAqIERvbWFpbjogWy1JbmZpbml0eSwgSW5maW5pdHldDQogICAqIFJhbmdlOiBbLTEsIDFdDQogICAqDQogICAqIGNvcygwKSAgICAgICAgID0gMQ0KICAgKiBjb3MoLTApICAgICAgICA9IDENCiAgICogY29zKEluZmluaXR5KSAgPSBOYU4NCiAgICogY29zKC1JbmZpbml0eSkgPSBOYU4NCiAgICogY29zKE5hTikgICAgICAgPSBOYU4NCiAgICoNCiAgICovDQogIFAuY29zaW5lID0gUC5jb3MgPSBmdW5jdGlvbiAoKSB7DQogICAgdmFyIHByLCBybSwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICBpZiAoIXguZCkgcmV0dXJuIG5ldyBDdG9yKE5hTik7DQoNCiAgICAvLyBjb3MoMCkgPSBjb3MoLTApID0gMQ0KICAgIGlmICgheC5kWzBdKSByZXR1cm4gbmV3IEN0b3IoMSk7DQoNCiAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KICAgIHJtID0gQ3Rvci5yb3VuZGluZzsNCiAgICBDdG9yLnByZWNpc2lvbiA9IHByICsgTWF0aC5tYXgoeC5lLCB4LnNkKCkpICsgTE9HX0JBU0U7DQogICAgQ3Rvci5yb3VuZGluZyA9IDE7DQoNCiAgICB4ID0gY29zaW5lKEN0b3IsIHRvTGVzc1RoYW5IYWxmUGkoQ3RvciwgeCkpOw0KDQogICAgQ3Rvci5wcmVjaXNpb24gPSBwcjsNCiAgICBDdG9yLnJvdW5kaW5nID0gcm07DQoNCiAgICByZXR1cm4gZmluYWxpc2UocXVhZHJhbnQgPT0gMiB8fCBxdWFkcmFudCA9PSAzID8geC5uZWcoKSA6IHgsIHByLCBybSwgdHJ1ZSk7DQogIH07DQoNCg0KICAvKg0KICAgKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgY3ViZSByb290IG9mIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwsIHJvdW5kZWQgdG8NCiAgICogYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogIGNicnQoMCkgID0gIDANCiAgICogIGNicnQoLTApID0gLTANCiAgICogIGNicnQoMSkgID0gIDENCiAgICogIGNicnQoLTEpID0gLTENCiAgICogIGNicnQoTikgID0gIE4NCiAgICogIGNicnQoLUkpID0gLUkNCiAgICogIGNicnQoSSkgID0gIEkNCiAgICoNCiAgICogTWF0aC5jYnJ0KHgpID0gKHggPCAwID8gLU1hdGgucG93KC14LCAxLzMpIDogTWF0aC5wb3coeCwgMS8zKSkNCiAgICoNCiAgICovDQogIFAuY3ViZVJvb3QgPSBQLmNicnQgPSBmdW5jdGlvbiAoKSB7DQogICAgdmFyIGUsIG0sIG4sIHIsIHJlcCwgcywgc2QsIHQsIHQzLCB0M3BsdXN4LA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmICgheC5pc0Zpbml0ZSgpIHx8IHguaXNaZXJvKCkpIHJldHVybiBuZXcgQ3Rvcih4KTsNCiAgICBleHRlcm5hbCA9IGZhbHNlOw0KDQogICAgLy8gSW5pdGlhbCBlc3RpbWF0ZS4NCiAgICBzID0geC5zICogbWF0aHBvdyh4LnMgKiB4LCAxIC8gMyk7DQoNCiAgICAgLy8gTWF0aC5jYnJ0IHVuZGVyZmxvdy9vdmVyZmxvdz8NCiAgICAgLy8gUGFzcyB4IHRvIE1hdGgucG93IGFzIGludGVnZXIsIHRoZW4gYWRqdXN0IHRoZSBleHBvbmVudCBvZiB0aGUgcmVzdWx0Lg0KICAgIGlmICghcyB8fCBNYXRoLmFicyhzKSA9PSAxIC8gMCkgew0KICAgICAgbiA9IGRpZ2l0c1RvU3RyaW5nKHguZCk7DQogICAgICBlID0geC5lOw0KDQogICAgICAvLyBBZGp1c3QgbiBleHBvbmVudCBzbyBpdCBpcyBhIG11bHRpcGxlIG9mIDMgYXdheSBmcm9tIHggZXhwb25lbnQuDQogICAgICBpZiAocyA9IChlIC0gbi5sZW5ndGggKyAxKSAlIDMpIG4gKz0gKHMgPT0gMSB8fCBzID09IC0yID8gJzAnIDogJzAwJyk7DQogICAgICBzID0gbWF0aHBvdyhuLCAxIC8gMyk7DQoNCiAgICAgIC8vIFJhcmVseSwgZSBtYXkgYmUgb25lIGxlc3MgdGhhbiB0aGUgcmVzdWx0IGV4cG9uZW50IHZhbHVlLg0KICAgICAgZSA9IG1hdGhmbG9vcigoZSArIDEpIC8gMykgLSAoZSAlIDMgPT0gKGUgPCAwID8gLTEgOiAyKSk7DQoNCiAgICAgIGlmIChzID09IDEgLyAwKSB7DQogICAgICAgIG4gPSAnNWUnICsgZTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIG4gPSBzLnRvRXhwb25lbnRpYWwoKTsNCiAgICAgICAgbiA9IG4uc2xpY2UoMCwgbi5pbmRleE9mKCdlJykgKyAxKSArIGU7DQogICAgICB9DQoNCiAgICAgIHIgPSBuZXcgQ3RvcihuKTsNCiAgICAgIHIucyA9IHguczsNCiAgICB9IGVsc2Ugew0KICAgICAgciA9IG5ldyBDdG9yKHMudG9TdHJpbmcoKSk7DQogICAgfQ0KDQogICAgc2QgPSAoZSA9IEN0b3IucHJlY2lzaW9uKSArIDM7DQoNCiAgICAvLyBIYWxsZXkncyBtZXRob2QuDQogICAgLy8gVE9ETz8gQ29tcGFyZSBOZXd0b24ncyBtZXRob2QuDQogICAgZm9yICg7Oykgew0KICAgICAgdCA9IHI7DQogICAgICB0MyA9IHQudGltZXModCkudGltZXModCk7DQogICAgICB0M3BsdXN4ID0gdDMucGx1cyh4KTsNCiAgICAgIHIgPSBkaXZpZGUodDNwbHVzeC5wbHVzKHgpLnRpbWVzKHQpLCB0M3BsdXN4LnBsdXModDMpLCBzZCArIDIsIDEpOw0KDQogICAgICAvLyBUT0RPPyBSZXBsYWNlIHdpdGggZm9yLWxvb3AgYW5kIGNoZWNrUm91bmRpbmdEaWdpdHMuDQogICAgICBpZiAoZGlnaXRzVG9TdHJpbmcodC5kKS5zbGljZSgwLCBzZCkgPT09IChuID0gZGlnaXRzVG9TdHJpbmcoci5kKSkuc2xpY2UoMCwgc2QpKSB7DQogICAgICAgIG4gPSBuLnNsaWNlKHNkIC0gMywgc2QgKyAxKTsNCg0KICAgICAgICAvLyBUaGUgNHRoIHJvdW5kaW5nIGRpZ2l0IG1heSBiZSBpbiBlcnJvciBieSAtMSBzbyBpZiB0aGUgNCByb3VuZGluZyBkaWdpdHMgYXJlIDk5OTkgb3IgNDk5OQ0KICAgICAgICAvLyAsIGkuZS4gYXBwcm9hY2hpbmcgYSByb3VuZGluZyBib3VuZGFyeSwgY29udGludWUgdGhlIGl0ZXJhdGlvbi4NCiAgICAgICAgaWYgKG4gPT0gJzk5OTknIHx8ICFyZXAgJiYgbiA9PSAnNDk5OScpIHsNCg0KICAgICAgICAgIC8vIE9uIHRoZSBmaXJzdCBpdGVyYXRpb24gb25seSwgY2hlY2sgdG8gc2VlIGlmIHJvdW5kaW5nIHVwIGdpdmVzIHRoZSBleGFjdCByZXN1bHQgYXMgdGhlDQogICAgICAgICAgLy8gbmluZXMgbWF5IGluZmluaXRlbHkgcmVwZWF0Lg0KICAgICAgICAgIGlmICghcmVwKSB7DQogICAgICAgICAgICBmaW5hbGlzZSh0LCBlICsgMSwgMCk7DQoNCiAgICAgICAgICAgIGlmICh0LnRpbWVzKHQpLnRpbWVzKHQpLmVxKHgpKSB7DQogICAgICAgICAgICAgIHIgPSB0Ow0KICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQoNCiAgICAgICAgICBzZCArPSA0Ow0KICAgICAgICAgIHJlcCA9IDE7DQogICAgICAgIH0gZWxzZSB7DQoNCiAgICAgICAgICAvLyBJZiB0aGUgcm91bmRpbmcgZGlnaXRzIGFyZSBudWxsLCAwezAsNH0gb3IgNTB7MCwzfSwgY2hlY2sgZm9yIGFuIGV4YWN0IHJlc3VsdC4NCiAgICAgICAgICAvLyBJZiBub3QsIHRoZW4gdGhlcmUgYXJlIGZ1cnRoZXIgZGlnaXRzIGFuZCBtIHdpbGwgYmUgdHJ1dGh5Lg0KICAgICAgICAgIGlmICghK24gfHwgIStuLnNsaWNlKDEpICYmIG4uY2hhckF0KDApID09ICc1Jykgew0KDQogICAgICAgICAgICAvLyBUcnVuY2F0ZSB0byB0aGUgZmlyc3Qgcm91bmRpbmcgZGlnaXQuDQogICAgICAgICAgICBmaW5hbGlzZShyLCBlICsgMSwgMSk7DQogICAgICAgICAgICBtID0gIXIudGltZXMocikudGltZXMocikuZXEoeCk7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQoNCiAgICBleHRlcm5hbCA9IHRydWU7DQoNCiAgICByZXR1cm4gZmluYWxpc2UociwgZSwgQ3Rvci5yb3VuZGluZywgbSk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyBvZiB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKi8NCiAgUC5kZWNpbWFsUGxhY2VzID0gUC5kcCA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgdywNCiAgICAgIGQgPSB0aGlzLmQsDQogICAgICBuID0gTmFOOw0KDQogICAgaWYgKGQpIHsNCiAgICAgIHcgPSBkLmxlbmd0aCAtIDE7DQogICAgICBuID0gKHcgLSBtYXRoZmxvb3IodGhpcy5lIC8gTE9HX0JBU0UpKSAqIExPR19CQVNFOw0KDQogICAgICAvLyBTdWJ0cmFjdCB0aGUgbnVtYmVyIG9mIHRyYWlsaW5nIHplcm9zIG9mIHRoZSBsYXN0IHdvcmQuDQogICAgICB3ID0gZFt3XTsNCiAgICAgIGlmICh3KSBmb3IgKDsgdyAlIDEwID09IDA7IHcgLz0gMTApIG4tLTsNCiAgICAgIGlmIChuIDwgMCkgbiA9IDA7DQogICAgfQ0KDQogICAgcmV0dXJuIG47DQogIH07DQoNCg0KICAvKg0KICAgKiAgbiAvIDAgPSBJDQogICAqICBuIC8gTiA9IE4NCiAgICogIG4gLyBJID0gMA0KICAgKiAgMCAvIG4gPSAwDQogICAqICAwIC8gMCA9IE4NCiAgICogIDAgLyBOID0gTg0KICAgKiAgMCAvIEkgPSAwDQogICAqICBOIC8gbiA9IE4NCiAgICogIE4gLyAwID0gTg0KICAgKiAgTiAvIE4gPSBODQogICAqICBOIC8gSSA9IE4NCiAgICogIEkgLyBuID0gSQ0KICAgKiAgSSAvIDAgPSBJDQogICAqICBJIC8gTiA9IE4NCiAgICogIEkgLyBJID0gTg0KICAgKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIGRpdmlkZWQgYnkgYHlgLCByb3VuZGVkIHRvDQogICAqIGBwcmVjaXNpb25gIHNpZ25pZmljYW50IGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqLw0KICBQLmRpdmlkZWRCeSA9IFAuZGl2ID0gZnVuY3Rpb24gKHkpIHsNCiAgICByZXR1cm4gZGl2aWRlKHRoaXMsIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHkpKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBpbnRlZ2VyIHBhcnQgb2YgZGl2aWRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbA0KICAgKiBieSB0aGUgdmFsdWUgb2YgYHlgLCByb3VuZGVkIHRvIGBwcmVjaXNpb25gIHNpZ25pZmljYW50IGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqLw0KICBQLmRpdmlkZWRUb0ludGVnZXJCeSA9IFAuZGl2VG9JbnQgPSBmdW5jdGlvbiAoeSkgew0KICAgIHZhciB4ID0gdGhpcywNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yOw0KICAgIHJldHVybiBmaW5hbGlzZShkaXZpZGUoeCwgbmV3IEN0b3IoeSksIDAsIDEsIDEpLCBDdG9yLnByZWNpc2lvbiwgQ3Rvci5yb3VuZGluZyk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIGlzIGVxdWFsIHRvIHRoZSB2YWx1ZSBvZiBgeWAsIG90aGVyd2lzZSByZXR1cm4gZmFsc2UuDQogICAqDQogICAqLw0KICBQLmVxdWFscyA9IFAuZXEgPSBmdW5jdGlvbiAoeSkgew0KICAgIHJldHVybiB0aGlzLmNtcCh5KSA9PT0gMDsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgcm91bmRlZCB0byBhIHdob2xlIG51bWJlciBpbiB0aGUNCiAgICogZGlyZWN0aW9uIG9mIG5lZ2F0aXZlIEluZmluaXR5Lg0KICAgKg0KICAgKi8NCiAgUC5mbG9vciA9IGZ1bmN0aW9uICgpIHsNCiAgICByZXR1cm4gZmluYWxpc2UobmV3IHRoaXMuY29uc3RydWN0b3IodGhpcyksIHRoaXMuZSArIDEsIDMpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpcyBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIG9mIGB5YCwgb3RoZXJ3aXNlIHJldHVybg0KICAgKiBmYWxzZS4NCiAgICoNCiAgICovDQogIFAuZ3JlYXRlclRoYW4gPSBQLmd0ID0gZnVuY3Rpb24gKHkpIHsNCiAgICByZXR1cm4gdGhpcy5jbXAoeSkgPiAwOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHZhbHVlIG9mIGB5YCwNCiAgICogb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4NCiAgICoNCiAgICovDQogIFAuZ3JlYXRlclRoYW5PckVxdWFsVG8gPSBQLmd0ZSA9IGZ1bmN0aW9uICh5KSB7DQogICAgdmFyIGsgPSB0aGlzLmNtcCh5KTsNCiAgICByZXR1cm4gayA9PSAxIHx8IGsgPT09IDA7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgaHlwZXJib2xpYyBjb3NpbmUgb2YgdGhlIHZhbHVlIGluIHJhZGlhbnMgb2YgdGhpcw0KICAgKiBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWzEsIEluZmluaXR5XQ0KICAgKg0KICAgKiBjb3NoKHgpID0gMSArIHheMi8yISArIHheNC80ISArIHheNi82ISArIC4uLg0KICAgKg0KICAgKiBjb3NoKDApICAgICAgICAgPSAxDQogICAqIGNvc2goLTApICAgICAgICA9IDENCiAgICogY29zaChJbmZpbml0eSkgID0gSW5maW5pdHkNCiAgICogY29zaCgtSW5maW5pdHkpID0gSW5maW5pdHkNCiAgICogY29zaChOYU4pICAgICAgID0gTmFODQogICAqDQogICAqICB4ICAgICAgICB0aW1lIHRha2VuIChtcykgICByZXN1bHQNCiAgICogMTAwMCAgICAgIDkgICAgICAgICAgICAgICAgIDkuODUwMzU1NTcwMDg1MjM0OTY5NGUrNDMzDQogICAqIDEwMDAwICAgICAyNSAgICAgICAgICAgICAgICA0LjQwMzQwOTExMjgzMTQ2MDc5MzZlKzQzNDINCiAgICogMTAwMDAwICAgIDE3MSAgICAgICAgICAgICAgIDEuNDAzMzMxNjgwMjEzMDYxNTg5N2UrNDM0MjkNCiAgICogMTAwMDAwMCAgIDM4MTcgICAgICAgICAgICAgIDEuNTE2NjA3Njk4NDAxMDQzNzcyNWUrNDM0Mjk0DQogICAqIDEwMDAwMDAwICBhYmFuZG9uZWQgYWZ0ZXIgMiBtaW51dGUgd2FpdA0KICAgKg0KICAgKiBUT0RPPyBDb21wYXJlIHBlcmZvcm1hbmNlIG9mIGNvc2goeCkgPSAwLjUgKiAoZXhwKHgpICsgZXhwKC14KSkNCiAgICoNCiAgICovDQogIFAuaHlwZXJib2xpY0Nvc2luZSA9IFAuY29zaCA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgaywgbiwgcHIsIHJtLCBsZW4sDQogICAgICB4ID0gdGhpcywNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yLA0KICAgICAgb25lID0gbmV3IEN0b3IoMSk7DQoNCiAgICBpZiAoIXguaXNGaW5pdGUoKSkgcmV0dXJuIG5ldyBDdG9yKHgucyA/IDEgLyAwIDogTmFOKTsNCiAgICBpZiAoeC5pc1plcm8oKSkgcmV0dXJuIG9uZTsNCg0KICAgIHByID0gQ3Rvci5wcmVjaXNpb247DQogICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KICAgIEN0b3IucHJlY2lzaW9uID0gcHIgKyBNYXRoLm1heCh4LmUsIHguc2QoKSkgKyA0Ow0KICAgIEN0b3Iucm91bmRpbmcgPSAxOw0KICAgIGxlbiA9IHguZC5sZW5ndGg7DQoNCiAgICAvLyBBcmd1bWVudCByZWR1Y3Rpb246IGNvcyg0eCkgPSAxIC0gOGNvc14yKHgpICsgOGNvc140KHgpICsgMQ0KICAgIC8vIGkuZS4gY29zKHgpID0gMSAtIGNvc14yKHgvNCkoOCAtIDhjb3NeMih4LzQpKQ0KDQogICAgLy8gRXN0aW1hdGUgdGhlIG9wdGltdW0gbnVtYmVyIG9mIHRpbWVzIHRvIHVzZSB0aGUgYXJndW1lbnQgcmVkdWN0aW9uLg0KICAgIC8vIFRPRE8/IEVzdGltYXRpb24gcmV1c2VkIGZyb20gY29zaW5lKCkgYW5kIG1heSBub3QgYmUgb3B0aW1hbCBoZXJlLg0KICAgIGlmIChsZW4gPCAzMikgew0KICAgICAgayA9IE1hdGguY2VpbChsZW4gLyAzKTsNCiAgICAgIG4gPSAoMSAvIHRpbnlQb3coNCwgaykpLnRvU3RyaW5nKCk7DQogICAgfSBlbHNlIHsNCiAgICAgIGsgPSAxNjsNCiAgICAgIG4gPSAnMi4zMjgzMDY0MzY1Mzg2OTYyODkwNjI1ZS0xMCc7DQogICAgfQ0KDQogICAgeCA9IHRheWxvclNlcmllcyhDdG9yLCAxLCB4LnRpbWVzKG4pLCBuZXcgQ3RvcigxKSwgdHJ1ZSk7DQoNCiAgICAvLyBSZXZlcnNlIGFyZ3VtZW50IHJlZHVjdGlvbg0KICAgIHZhciBjb3NoMl94LA0KICAgICAgaSA9IGssDQogICAgICBkOCA9IG5ldyBDdG9yKDgpOw0KICAgIGZvciAoOyBpLS07KSB7DQogICAgICBjb3NoMl94ID0geC50aW1lcyh4KTsNCiAgICAgIHggPSBvbmUubWludXMoY29zaDJfeC50aW1lcyhkOC5taW51cyhjb3NoMl94LnRpbWVzKGQ4KSkpKTsNCiAgICB9DQoNCiAgICByZXR1cm4gZmluYWxpc2UoeCwgQ3Rvci5wcmVjaXNpb24gPSBwciwgQ3Rvci5yb3VuZGluZyA9IHJtLCB0cnVlKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBoeXBlcmJvbGljIHNpbmUgb2YgdGhlIHZhbHVlIGluIHJhZGlhbnMgb2YgdGhpcw0KICAgKiBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWy1JbmZpbml0eSwgSW5maW5pdHldDQogICAqDQogICAqIHNpbmgoeCkgPSB4ICsgeF4zLzMhICsgeF41LzUhICsgeF43LzchICsgLi4uDQogICAqDQogICAqIHNpbmgoMCkgICAgICAgICA9IDANCiAgICogc2luaCgtMCkgICAgICAgID0gLTANCiAgICogc2luaChJbmZpbml0eSkgID0gSW5maW5pdHkNCiAgICogc2luaCgtSW5maW5pdHkpID0gLUluZmluaXR5DQogICAqIHNpbmgoTmFOKSAgICAgICA9IE5hTg0KICAgKg0KICAgKiB4ICAgICAgICB0aW1lIHRha2VuIChtcykNCiAgICogMTAgICAgICAgMiBtcw0KICAgKiAxMDAgICAgICA1IG1zDQogICAqIDEwMDAgICAgIDE0IG1zDQogICAqIDEwMDAwICAgIDgyIG1zDQogICAqIDEwMDAwMCAgIDg4NiBtcyAgICAgICAgICAgIDEuNDAzMzMxNjgwMjEzMDYxNTg5N2UrNDM0MjkNCiAgICogMjAwMDAwICAgMjYxMyBtcw0KICAgKiAzMDAwMDAgICA1NDA3IG1zDQogICAqIDQwMDAwMCAgIDg4MjQgbXMNCiAgICogNTAwMDAwICAgMTMwMjYgbXMgICAgICAgICAgOC43MDgwNjQzNjEyNzE4MDg0MTI5ZSsyMTcxNDYNCiAgICogMTAwMDAwMCAgNDg1NDMgbXMNCiAgICoNCiAgICogVE9ETz8gQ29tcGFyZSBwZXJmb3JtYW5jZSBvZiBzaW5oKHgpID0gMC41ICogKGV4cCh4KSAtIGV4cCgteCkpDQogICAqDQogICAqLw0KICBQLmh5cGVyYm9saWNTaW5lID0gUC5zaW5oID0gZnVuY3Rpb24gKCkgew0KICAgIHZhciBrLCBwciwgcm0sIGxlbiwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICBpZiAoIXguaXNGaW5pdGUoKSB8fCB4LmlzWmVybygpKSByZXR1cm4gbmV3IEN0b3IoeCk7DQoNCiAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KICAgIHJtID0gQ3Rvci5yb3VuZGluZzsNCiAgICBDdG9yLnByZWNpc2lvbiA9IHByICsgTWF0aC5tYXgoeC5lLCB4LnNkKCkpICsgNDsNCiAgICBDdG9yLnJvdW5kaW5nID0gMTsNCiAgICBsZW4gPSB4LmQubGVuZ3RoOw0KDQogICAgaWYgKGxlbiA8IDMpIHsNCiAgICAgIHggPSB0YXlsb3JTZXJpZXMoQ3RvciwgMiwgeCwgeCwgdHJ1ZSk7DQogICAgfSBlbHNlIHsNCg0KICAgICAgLy8gQWx0ZXJuYXRpdmUgYXJndW1lbnQgcmVkdWN0aW9uOiBzaW5oKDN4KSA9IHNpbmgoeCkoMyArIDRzaW5oXjIoeCkpDQogICAgICAvLyBpLmUuIHNpbmgoeCkgPSBzaW5oKHgvMykoMyArIDRzaW5oXjIoeC8zKSkNCiAgICAgIC8vIDMgbXVsdGlwbGljYXRpb25zIGFuZCAxIGFkZGl0aW9uDQoNCiAgICAgIC8vIEFyZ3VtZW50IHJlZHVjdGlvbjogc2luaCg1eCkgPSBzaW5oKHgpKDUgKyBzaW5oXjIoeCkoMjAgKyAxNnNpbmheMih4KSkpDQogICAgICAvLyBpLmUuIHNpbmgoeCkgPSBzaW5oKHgvNSkoNSArIHNpbmheMih4LzUpKDIwICsgMTZzaW5oXjIoeC81KSkpDQogICAgICAvLyA0IG11bHRpcGxpY2F0aW9ucyBhbmQgMiBhZGRpdGlvbnMNCg0KICAgICAgLy8gRXN0aW1hdGUgdGhlIG9wdGltdW0gbnVtYmVyIG9mIHRpbWVzIHRvIHVzZSB0aGUgYXJndW1lbnQgcmVkdWN0aW9uLg0KICAgICAgayA9IDEuNCAqIE1hdGguc3FydChsZW4pOw0KICAgICAgayA9IGsgPiAxNiA/IDE2IDogayB8IDA7DQoNCiAgICAgIHggPSB4LnRpbWVzKDEgLyB0aW55UG93KDUsIGspKTsNCiAgICAgIHggPSB0YXlsb3JTZXJpZXMoQ3RvciwgMiwgeCwgeCwgdHJ1ZSk7DQoNCiAgICAgIC8vIFJldmVyc2UgYXJndW1lbnQgcmVkdWN0aW9uDQogICAgICB2YXIgc2luaDJfeCwNCiAgICAgICAgZDUgPSBuZXcgQ3Rvcig1KSwNCiAgICAgICAgZDE2ID0gbmV3IEN0b3IoMTYpLA0KICAgICAgICBkMjAgPSBuZXcgQ3RvcigyMCk7DQogICAgICBmb3IgKDsgay0tOykgew0KICAgICAgICBzaW5oMl94ID0geC50aW1lcyh4KTsNCiAgICAgICAgeCA9IHgudGltZXMoZDUucGx1cyhzaW5oMl94LnRpbWVzKGQxNi50aW1lcyhzaW5oMl94KS5wbHVzKGQyMCkpKSk7DQogICAgICB9DQogICAgfQ0KDQogICAgQ3Rvci5wcmVjaXNpb24gPSBwcjsNCiAgICBDdG9yLnJvdW5kaW5nID0gcm07DQoNCiAgICByZXR1cm4gZmluYWxpc2UoeCwgcHIsIHJtLCB0cnVlKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBoeXBlcmJvbGljIHRhbmdlbnQgb2YgdGhlIHZhbHVlIGluIHJhZGlhbnMgb2YgdGhpcw0KICAgKiBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWy0xLCAxXQ0KICAgKg0KICAgKiB0YW5oKHgpID0gc2luaCh4KSAvIGNvc2goeCkNCiAgICoNCiAgICogdGFuaCgwKSAgICAgICAgID0gMA0KICAgKiB0YW5oKC0wKSAgICAgICAgPSAtMA0KICAgKiB0YW5oKEluZmluaXR5KSAgPSAxDQogICAqIHRhbmgoLUluZmluaXR5KSA9IC0xDQogICAqIHRhbmgoTmFOKSAgICAgICA9IE5hTg0KICAgKg0KICAgKi8NCiAgUC5oeXBlcmJvbGljVGFuZ2VudCA9IFAudGFuaCA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgcHIsIHJtLA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmICgheC5pc0Zpbml0ZSgpKSByZXR1cm4gbmV3IEN0b3IoeC5zKTsNCiAgICBpZiAoeC5pc1plcm8oKSkgcmV0dXJuIG5ldyBDdG9yKHgpOw0KDQogICAgcHIgPSBDdG9yLnByZWNpc2lvbjsNCiAgICBybSA9IEN0b3Iucm91bmRpbmc7DQogICAgQ3Rvci5wcmVjaXNpb24gPSBwciArIDc7DQogICAgQ3Rvci5yb3VuZGluZyA9IDE7DQoNCiAgICByZXR1cm4gZGl2aWRlKHguc2luaCgpLCB4LmNvc2goKSwgQ3Rvci5wcmVjaXNpb24gPSBwciwgQ3Rvci5yb3VuZGluZyA9IHJtKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBhcmNjb3NpbmUgKGludmVyc2UgY29zaW5lKSBpbiByYWRpYW5zIG9mIHRoZSB2YWx1ZSBvZg0KICAgKiB0aGlzIERlY2ltYWwuDQogICAqDQogICAqIERvbWFpbjogWy0xLCAxXQ0KICAgKiBSYW5nZTogWzAsIHBpXQ0KICAgKg0KICAgKiBhY29zKHgpID0gcGkvMiAtIGFzaW4oeCkNCiAgICoNCiAgICogYWNvcygwKSAgICAgICA9IHBpLzINCiAgICogYWNvcygtMCkgICAgICA9IHBpLzINCiAgICogYWNvcygxKSAgICAgICA9IDANCiAgICogYWNvcygtMSkgICAgICA9IHBpDQogICAqIGFjb3MoMS8yKSAgICAgPSBwaS8zDQogICAqIGFjb3MoLTEvMikgICAgPSAyKnBpLzMNCiAgICogYWNvcyh8eHwgPiAxKSA9IE5hTg0KICAgKiBhY29zKE5hTikgICAgID0gTmFODQogICAqDQogICAqLw0KICBQLmludmVyc2VDb3NpbmUgPSBQLmFjb3MgPSBmdW5jdGlvbiAoKSB7DQogICAgdmFyIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3IsDQogICAgICBrID0geC5hYnMoKS5jbXAoMSksDQogICAgICBwciA9IEN0b3IucHJlY2lzaW9uLA0KICAgICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KDQogICAgaWYgKGsgIT09IC0xKSB7DQogICAgICByZXR1cm4gayA9PT0gMA0KICAgICAgICAvLyB8eHwgaXMgMQ0KICAgICAgICA/IHguaXNOZWcoKSA/IGdldFBpKEN0b3IsIHByLCBybSkgOiBuZXcgQ3RvcigwKQ0KICAgICAgICAvLyB8eHwgPiAxIG9yIHggaXMgTmFODQogICAgICAgIDogbmV3IEN0b3IoTmFOKTsNCiAgICB9DQoNCiAgICBpZiAoeC5pc1plcm8oKSkgcmV0dXJuIGdldFBpKEN0b3IsIHByICsgNCwgcm0pLnRpbWVzKDAuNSk7DQoNCiAgICAvLyBUT0RPPyBTcGVjaWFsIGNhc2UgYWNvcygwLjUpID0gcGkvMyBhbmQgYWNvcygtMC41KSA9IDIqcGkvMw0KDQogICAgQ3Rvci5wcmVjaXNpb24gPSBwciArIDY7DQogICAgQ3Rvci5yb3VuZGluZyA9IDE7DQoNCiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL01pa2VNY2wvZGVjaW1hbC5qcy9wdWxsLzIxNw0KICAgIHggPSBuZXcgQ3RvcigxKS5taW51cyh4KS5kaXYoeC5wbHVzKDEpKS5zcXJ0KCkuYXRhbigpOw0KDQogICAgQ3Rvci5wcmVjaXNpb24gPSBwcjsNCiAgICBDdG9yLnJvdW5kaW5nID0gcm07DQoNCiAgICByZXR1cm4geC50aW1lcygyKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBpbnZlcnNlIG9mIHRoZSBoeXBlcmJvbGljIGNvc2luZSBpbiByYWRpYW5zIG9mIHRoZQ0KICAgKiB2YWx1ZSBvZiB0aGlzIERlY2ltYWwuDQogICAqDQogICAqIERvbWFpbjogWzEsIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWzAsIEluZmluaXR5XQ0KICAgKg0KICAgKiBhY29zaCh4KSA9IGxuKHggKyBzcXJ0KHheMiAtIDEpKQ0KICAgKg0KICAgKiBhY29zaCh4IDwgMSkgICAgID0gTmFODQogICAqIGFjb3NoKE5hTikgICAgICAgPSBOYU4NCiAgICogYWNvc2goSW5maW5pdHkpICA9IEluZmluaXR5DQogICAqIGFjb3NoKC1JbmZpbml0eSkgPSBOYU4NCiAgICogYWNvc2goMCkgICAgICAgICA9IE5hTg0KICAgKiBhY29zaCgtMCkgICAgICAgID0gTmFODQogICAqIGFjb3NoKDEpICAgICAgICAgPSAwDQogICAqIGFjb3NoKC0xKSAgICAgICAgPSBOYU4NCiAgICoNCiAgICovDQogIFAuaW52ZXJzZUh5cGVyYm9saWNDb3NpbmUgPSBQLmFjb3NoID0gZnVuY3Rpb24gKCkgew0KICAgIHZhciBwciwgcm0sDQogICAgICB4ID0gdGhpcywNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yOw0KDQogICAgaWYgKHgubHRlKDEpKSByZXR1cm4gbmV3IEN0b3IoeC5lcSgxKSA/IDAgOiBOYU4pOw0KICAgIGlmICgheC5pc0Zpbml0ZSgpKSByZXR1cm4gbmV3IEN0b3IoeCk7DQoNCiAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KICAgIHJtID0gQ3Rvci5yb3VuZGluZzsNCiAgICBDdG9yLnByZWNpc2lvbiA9IHByICsgTWF0aC5tYXgoTWF0aC5hYnMoeC5lKSwgeC5zZCgpKSArIDQ7DQogICAgQ3Rvci5yb3VuZGluZyA9IDE7DQogICAgZXh0ZXJuYWwgPSBmYWxzZTsNCg0KICAgIHggPSB4LnRpbWVzKHgpLm1pbnVzKDEpLnNxcnQoKS5wbHVzKHgpOw0KDQogICAgZXh0ZXJuYWwgPSB0cnVlOw0KICAgIEN0b3IucHJlY2lzaW9uID0gcHI7DQogICAgQ3Rvci5yb3VuZGluZyA9IHJtOw0KDQogICAgcmV0dXJuIHgubG4oKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBpbnZlcnNlIG9mIHRoZSBoeXBlcmJvbGljIHNpbmUgaW4gcmFkaWFucyBvZiB0aGUgdmFsdWUNCiAgICogb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWy1JbmZpbml0eSwgSW5maW5pdHldDQogICAqDQogICAqIGFzaW5oKHgpID0gbG4oeCArIHNxcnQoeF4yICsgMSkpDQogICAqDQogICAqIGFzaW5oKE5hTikgICAgICAgPSBOYU4NCiAgICogYXNpbmgoSW5maW5pdHkpICA9IEluZmluaXR5DQogICAqIGFzaW5oKC1JbmZpbml0eSkgPSAtSW5maW5pdHkNCiAgICogYXNpbmgoMCkgICAgICAgICA9IDANCiAgICogYXNpbmgoLTApICAgICAgICA9IC0wDQogICAqDQogICAqLw0KICBQLmludmVyc2VIeXBlcmJvbGljU2luZSA9IFAuYXNpbmggPSBmdW5jdGlvbiAoKSB7DQogICAgdmFyIHByLCBybSwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICBpZiAoIXguaXNGaW5pdGUoKSB8fCB4LmlzWmVybygpKSByZXR1cm4gbmV3IEN0b3IoeCk7DQoNCiAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KICAgIHJtID0gQ3Rvci5yb3VuZGluZzsNCiAgICBDdG9yLnByZWNpc2lvbiA9IHByICsgMiAqIE1hdGgubWF4KE1hdGguYWJzKHguZSksIHguc2QoKSkgKyA2Ow0KICAgIEN0b3Iucm91bmRpbmcgPSAxOw0KICAgIGV4dGVybmFsID0gZmFsc2U7DQoNCiAgICB4ID0geC50aW1lcyh4KS5wbHVzKDEpLnNxcnQoKS5wbHVzKHgpOw0KDQogICAgZXh0ZXJuYWwgPSB0cnVlOw0KICAgIEN0b3IucHJlY2lzaW9uID0gcHI7DQogICAgQ3Rvci5yb3VuZGluZyA9IHJtOw0KDQogICAgcmV0dXJuIHgubG4oKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBpbnZlcnNlIG9mIHRoZSBoeXBlcmJvbGljIHRhbmdlbnQgaW4gcmFkaWFucyBvZiB0aGUNCiAgICogdmFsdWUgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstMSwgMV0NCiAgICogUmFuZ2U6IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKg0KICAgKiBhdGFuaCh4KSA9IDAuNSAqIGxuKCgxICsgeCkgLyAoMSAtIHgpKQ0KICAgKg0KICAgKiBhdGFuaCh8eHwgPiAxKSAgID0gTmFODQogICAqIGF0YW5oKE5hTikgICAgICAgPSBOYU4NCiAgICogYXRhbmgoSW5maW5pdHkpICA9IE5hTg0KICAgKiBhdGFuaCgtSW5maW5pdHkpID0gTmFODQogICAqIGF0YW5oKDApICAgICAgICAgPSAwDQogICAqIGF0YW5oKC0wKSAgICAgICAgPSAtMA0KICAgKiBhdGFuaCgxKSAgICAgICAgID0gSW5maW5pdHkNCiAgICogYXRhbmgoLTEpICAgICAgICA9IC1JbmZpbml0eQ0KICAgKg0KICAgKi8NCiAgUC5pbnZlcnNlSHlwZXJib2xpY1RhbmdlbnQgPSBQLmF0YW5oID0gZnVuY3Rpb24gKCkgew0KICAgIHZhciBwciwgcm0sIHdwciwgeHNkLA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmICgheC5pc0Zpbml0ZSgpKSByZXR1cm4gbmV3IEN0b3IoTmFOKTsNCiAgICBpZiAoeC5lID49IDApIHJldHVybiBuZXcgQ3Rvcih4LmFicygpLmVxKDEpID8geC5zIC8gMCA6IHguaXNaZXJvKCkgPyB4IDogTmFOKTsNCg0KICAgIHByID0gQ3Rvci5wcmVjaXNpb247DQogICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KICAgIHhzZCA9IHguc2QoKTsNCg0KICAgIGlmIChNYXRoLm1heCh4c2QsIHByKSA8IDIgKiAteC5lIC0gMSkgcmV0dXJuIGZpbmFsaXNlKG5ldyBDdG9yKHgpLCBwciwgcm0sIHRydWUpOw0KDQogICAgQ3Rvci5wcmVjaXNpb24gPSB3cHIgPSB4c2QgLSB4LmU7DQoNCiAgICB4ID0gZGl2aWRlKHgucGx1cygxKSwgbmV3IEN0b3IoMSkubWludXMoeCksIHdwciArIHByLCAxKTsNCg0KICAgIEN0b3IucHJlY2lzaW9uID0gcHIgKyA0Ow0KICAgIEN0b3Iucm91bmRpbmcgPSAxOw0KDQogICAgeCA9IHgubG4oKTsNCg0KICAgIEN0b3IucHJlY2lzaW9uID0gcHI7DQogICAgQ3Rvci5yb3VuZGluZyA9IHJtOw0KDQogICAgcmV0dXJuIHgudGltZXMoMC41KTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBhcmNzaW5lIChpbnZlcnNlIHNpbmUpIGluIHJhZGlhbnMgb2YgdGhlIHZhbHVlIG9mIHRoaXMNCiAgICogRGVjaW1hbC4NCiAgICoNCiAgICogRG9tYWluOiBbLUluZmluaXR5LCBJbmZpbml0eV0NCiAgICogUmFuZ2U6IFstcGkvMiwgcGkvMl0NCiAgICoNCiAgICogYXNpbih4KSA9IDIqYXRhbih4LygxICsgc3FydCgxIC0geF4yKSkpDQogICAqDQogICAqIGFzaW4oMCkgICAgICAgPSAwDQogICAqIGFzaW4oLTApICAgICAgPSAtMA0KICAgKiBhc2luKDEvMikgICAgID0gcGkvNg0KICAgKiBhc2luKC0xLzIpICAgID0gLXBpLzYNCiAgICogYXNpbigxKSAgICAgICA9IHBpLzINCiAgICogYXNpbigtMSkgICAgICA9IC1waS8yDQogICAqIGFzaW4ofHh8ID4gMSkgPSBOYU4NCiAgICogYXNpbihOYU4pICAgICA9IE5hTg0KICAgKg0KICAgKiBUT0RPPyBDb21wYXJlIHBlcmZvcm1hbmNlIG9mIFRheWxvciBzZXJpZXMuDQogICAqDQogICAqLw0KICBQLmludmVyc2VTaW5lID0gUC5hc2luID0gZnVuY3Rpb24gKCkgew0KICAgIHZhciBoYWxmUGksIGssDQogICAgICBwciwgcm0sDQogICAgICB4ID0gdGhpcywNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yOw0KDQogICAgaWYgKHguaXNaZXJvKCkpIHJldHVybiBuZXcgQ3Rvcih4KTsNCg0KICAgIGsgPSB4LmFicygpLmNtcCgxKTsNCiAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KICAgIHJtID0gQ3Rvci5yb3VuZGluZzsNCg0KICAgIGlmIChrICE9PSAtMSkgew0KDQogICAgICAvLyB8eHwgaXMgMQ0KICAgICAgaWYgKGsgPT09IDApIHsNCiAgICAgICAgaGFsZlBpID0gZ2V0UGkoQ3RvciwgcHIgKyA0LCBybSkudGltZXMoMC41KTsNCiAgICAgICAgaGFsZlBpLnMgPSB4LnM7DQogICAgICAgIHJldHVybiBoYWxmUGk7DQogICAgICB9DQoNCiAgICAgIC8vIHx4fCA+IDEgb3IgeCBpcyBOYU4NCiAgICAgIHJldHVybiBuZXcgQ3RvcihOYU4pOw0KICAgIH0NCg0KICAgIC8vIFRPRE8/IFNwZWNpYWwgY2FzZSBhc2luKDEvMikgPSBwaS82IGFuZCBhc2luKC0xLzIpID0gLXBpLzYNCg0KICAgIEN0b3IucHJlY2lzaW9uID0gcHIgKyA2Ow0KICAgIEN0b3Iucm91bmRpbmcgPSAxOw0KDQogICAgeCA9IHguZGl2KG5ldyBDdG9yKDEpLm1pbnVzKHgudGltZXMoeCkpLnNxcnQoKS5wbHVzKDEpKS5hdGFuKCk7DQoNCiAgICBDdG9yLnByZWNpc2lvbiA9IHByOw0KICAgIEN0b3Iucm91bmRpbmcgPSBybTsNCg0KICAgIHJldHVybiB4LnRpbWVzKDIpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGFyY3RhbmdlbnQgKGludmVyc2UgdGFuZ2VudCkgaW4gcmFkaWFucyBvZiB0aGUgdmFsdWUNCiAgICogb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWy1waS8yLCBwaS8yXQ0KICAgKg0KICAgKiBhdGFuKHgpID0geCAtIHheMy8zICsgeF41LzUgLSB4XjcvNyArIC4uLg0KICAgKg0KICAgKiBhdGFuKDApICAgICAgICAgPSAwDQogICAqIGF0YW4oLTApICAgICAgICA9IC0wDQogICAqIGF0YW4oMSkgICAgICAgICA9IHBpLzQNCiAgICogYXRhbigtMSkgICAgICAgID0gLXBpLzQNCiAgICogYXRhbihJbmZpbml0eSkgID0gcGkvMg0KICAgKiBhdGFuKC1JbmZpbml0eSkgPSAtcGkvMg0KICAgKiBhdGFuKE5hTikgICAgICAgPSBOYU4NCiAgICoNCiAgICovDQogIFAuaW52ZXJzZVRhbmdlbnQgPSBQLmF0YW4gPSBmdW5jdGlvbiAoKSB7DQogICAgdmFyIGksIGosIGssIG4sIHB4LCB0LCByLCB3cHIsIHgyLA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvciwNCiAgICAgIHByID0gQ3Rvci5wcmVjaXNpb24sDQogICAgICBybSA9IEN0b3Iucm91bmRpbmc7DQoNCiAgICBpZiAoIXguaXNGaW5pdGUoKSkgew0KICAgICAgaWYgKCF4LnMpIHJldHVybiBuZXcgQ3RvcihOYU4pOw0KICAgICAgaWYgKHByICsgNCA8PSBQSV9QUkVDSVNJT04pIHsNCiAgICAgICAgciA9IGdldFBpKEN0b3IsIHByICsgNCwgcm0pLnRpbWVzKDAuNSk7DQogICAgICAgIHIucyA9IHguczsNCiAgICAgICAgcmV0dXJuIHI7DQogICAgICB9DQogICAgfSBlbHNlIGlmICh4LmlzWmVybygpKSB7DQogICAgICByZXR1cm4gbmV3IEN0b3IoeCk7DQogICAgfSBlbHNlIGlmICh4LmFicygpLmVxKDEpICYmIHByICsgNCA8PSBQSV9QUkVDSVNJT04pIHsNCiAgICAgIHIgPSBnZXRQaShDdG9yLCBwciArIDQsIHJtKS50aW1lcygwLjI1KTsNCiAgICAgIHIucyA9IHguczsNCiAgICAgIHJldHVybiByOw0KICAgIH0NCg0KICAgIEN0b3IucHJlY2lzaW9uID0gd3ByID0gcHIgKyAxMDsNCiAgICBDdG9yLnJvdW5kaW5nID0gMTsNCg0KICAgIC8vIFRPRE8/IGlmICh4ID49IDEgJiYgcHIgPD0gUElfUFJFQ0lTSU9OKSBhdGFuKHgpID0gaGFsZlBpICogeC5zIC0gYXRhbigxIC8geCk7DQoNCiAgICAvLyBBcmd1bWVudCByZWR1Y3Rpb24NCiAgICAvLyBFbnN1cmUgfHh8IDwgMC40Mg0KICAgIC8vIGF0YW4oeCkgPSAyICogYXRhbih4IC8gKDEgKyBzcXJ0KDEgKyB4XjIpKSkNCg0KICAgIGsgPSBNYXRoLm1pbigyOCwgd3ByIC8gTE9HX0JBU0UgKyAyIHwgMCk7DQoNCiAgICBmb3IgKGkgPSBrOyBpOyAtLWkpIHggPSB4LmRpdih4LnRpbWVzKHgpLnBsdXMoMSkuc3FydCgpLnBsdXMoMSkpOw0KDQogICAgZXh0ZXJuYWwgPSBmYWxzZTsNCg0KICAgIGogPSBNYXRoLmNlaWwod3ByIC8gTE9HX0JBU0UpOw0KICAgIG4gPSAxOw0KICAgIHgyID0geC50aW1lcyh4KTsNCiAgICByID0gbmV3IEN0b3IoeCk7DQogICAgcHggPSB4Ow0KDQogICAgLy8gYXRhbih4KSA9IHggLSB4XjMvMyArIHheNS81IC0geF43LzcgKyAuLi4NCiAgICBmb3IgKDsgaSAhPT0gLTE7KSB7DQogICAgICBweCA9IHB4LnRpbWVzKHgyKTsNCiAgICAgIHQgPSByLm1pbnVzKHB4LmRpdihuICs9IDIpKTsNCg0KICAgICAgcHggPSBweC50aW1lcyh4Mik7DQogICAgICByID0gdC5wbHVzKHB4LmRpdihuICs9IDIpKTsNCg0KICAgICAgaWYgKHIuZFtqXSAhPT0gdm9pZCAwKSBmb3IgKGkgPSBqOyByLmRbaV0gPT09IHQuZFtpXSAmJiBpLS07KTsNCiAgICB9DQoNCiAgICBpZiAoaykgciA9IHIudGltZXMoMiA8PCAoayAtIDEpKTsNCg0KICAgIGV4dGVybmFsID0gdHJ1ZTsNCg0KICAgIHJldHVybiBmaW5hbGlzZShyLCBDdG9yLnByZWNpc2lvbiA9IHByLCBDdG9yLnJvdW5kaW5nID0gcm0sIHRydWUpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpcyBhIGZpbml0ZSBudW1iZXIsIG90aGVyd2lzZSByZXR1cm4gZmFsc2UuDQogICAqDQogICAqLw0KICBQLmlzRmluaXRlID0gZnVuY3Rpb24gKCkgew0KICAgIHJldHVybiAhIXRoaXMuZDsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgaXMgYW4gaW50ZWdlciwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4NCiAgICoNCiAgICovDQogIFAuaXNJbnRlZ2VyID0gUC5pc0ludCA9IGZ1bmN0aW9uICgpIHsNCiAgICByZXR1cm4gISF0aGlzLmQgJiYgbWF0aGZsb29yKHRoaXMuZSAvIExPR19CQVNFKSA+IHRoaXMuZC5sZW5ndGggLSAyOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpcyBOYU4sIG90aGVyd2lzZSByZXR1cm4gZmFsc2UuDQogICAqDQogICAqLw0KICBQLmlzTmFOID0gZnVuY3Rpb24gKCkgew0KICAgIHJldHVybiAhdGhpcy5zOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpcyBuZWdhdGl2ZSwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4NCiAgICoNCiAgICovDQogIFAuaXNOZWdhdGl2ZSA9IFAuaXNOZWcgPSBmdW5jdGlvbiAoKSB7DQogICAgcmV0dXJuIHRoaXMucyA8IDA7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIGlzIHBvc2l0aXZlLCBvdGhlcndpc2UgcmV0dXJuIGZhbHNlLg0KICAgKg0KICAgKi8NCiAgUC5pc1Bvc2l0aXZlID0gUC5pc1BvcyA9IGZ1bmN0aW9uICgpIHsNCiAgICByZXR1cm4gdGhpcy5zID4gMDsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgaXMgMCBvciAtMCwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4NCiAgICoNCiAgICovDQogIFAuaXNaZXJvID0gZnVuY3Rpb24gKCkgew0KICAgIHJldHVybiAhIXRoaXMuZCAmJiB0aGlzLmRbMF0gPT09IDA7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIGlzIGxlc3MgdGhhbiBgeWAsIG90aGVyd2lzZSByZXR1cm4gZmFsc2UuDQogICAqDQogICAqLw0KICBQLmxlc3NUaGFuID0gUC5sdCA9IGZ1bmN0aW9uICh5KSB7DQogICAgcmV0dXJuIHRoaXMuY21wKHkpIDwgMDsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGB5YCwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4NCiAgICoNCiAgICovDQogIFAubGVzc1RoYW5PckVxdWFsVG8gPSBQLmx0ZSA9IGZ1bmN0aW9uICh5KSB7DQogICAgcmV0dXJuIHRoaXMuY21wKHkpIDwgMTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiB0aGUgbG9nYXJpdGhtIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgdG8gdGhlIHNwZWNpZmllZCBiYXNlLCByb3VuZGVkIHRvIGBwcmVjaXNpb25gDQogICAqIHNpZ25pZmljYW50IGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqIElmIG5vIGJhc2UgaXMgc3BlY2lmaWVkLCByZXR1cm4gbG9nWzEwXShhcmcpLg0KICAgKg0KICAgKiBsb2dbYmFzZV0oYXJnKSA9IGxuKGFyZykgLyBsbihiYXNlKQ0KICAgKg0KICAgKiBUaGUgcmVzdWx0IHdpbGwgYWx3YXlzIGJlIGNvcnJlY3RseSByb3VuZGVkIGlmIHRoZSBiYXNlIG9mIHRoZSBsb2cgaXMgMTAsIGFuZCAnYWxtb3N0IGFsd2F5cycNCiAgICogb3RoZXJ3aXNlOg0KICAgKg0KICAgKiBEZXBlbmRpbmcgb24gdGhlIHJvdW5kaW5nIG1vZGUsIHRoZSByZXN1bHQgbWF5IGJlIGluY29ycmVjdGx5IHJvdW5kZWQgaWYgdGhlIGZpcnN0IGZpZnRlZW4NCiAgICogcm91bmRpbmcgZGlnaXRzIGFyZSBbNDldOTk5OTk5OTk5OTk5OTkgb3IgWzUwXTAwMDAwMDAwMDAwMDAwLiBJbiB0aGF0IGNhc2UsIHRoZSBtYXhpbXVtIGVycm9yDQogICAqIGJldHdlZW4gdGhlIHJlc3VsdCBhbmQgdGhlIGNvcnJlY3RseSByb3VuZGVkIHJlc3VsdCB3aWxsIGJlIG9uZSB1bHAgKHVuaXQgaW4gdGhlIGxhc3QgcGxhY2UpLg0KICAgKg0KICAgKiBsb2dbLWJdKGEpICAgICAgID0gTmFODQogICAqIGxvZ1swXShhKSAgICAgICAgPSBOYU4NCiAgICogbG9nWzFdKGEpICAgICAgICA9IE5hTg0KICAgKiBsb2dbTmFOXShhKSAgICAgID0gTmFODQogICAqIGxvZ1tJbmZpbml0eV0oYSkgPSBOYU4NCiAgICogbG9nW2JdKDApICAgICAgICA9IC1JbmZpbml0eQ0KICAgKiBsb2dbYl0oLTApICAgICAgID0gLUluZmluaXR5DQogICAqIGxvZ1tiXSgtYSkgICAgICAgPSBOYU4NCiAgICogbG9nW2JdKDEpICAgICAgICA9IDANCiAgICogbG9nW2JdKEluZmluaXR5KSA9IEluZmluaXR5DQogICAqIGxvZ1tiXShOYU4pICAgICAgPSBOYU4NCiAgICoNCiAgICogW2Jhc2VdIHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBUaGUgYmFzZSBvZiB0aGUgbG9nYXJpdGhtLg0KICAgKg0KICAgKi8NCiAgUC5sb2dhcml0aG0gPSBQLmxvZyA9IGZ1bmN0aW9uIChiYXNlKSB7DQogICAgdmFyIGlzQmFzZTEwLCBkLCBkZW5vbWluYXRvciwgaywgaW5mLCBudW0sIHNkLCByLA0KICAgICAgYXJnID0gdGhpcywNCiAgICAgIEN0b3IgPSBhcmcuY29uc3RydWN0b3IsDQogICAgICBwciA9IEN0b3IucHJlY2lzaW9uLA0KICAgICAgcm0gPSBDdG9yLnJvdW5kaW5nLA0KICAgICAgZ3VhcmQgPSA1Ow0KDQogICAgLy8gRGVmYXVsdCBiYXNlIGlzIDEwLg0KICAgIGlmIChiYXNlID09IG51bGwpIHsNCiAgICAgIGJhc2UgPSBuZXcgQ3RvcigxMCk7DQogICAgICBpc0Jhc2UxMCA9IHRydWU7DQogICAgfSBlbHNlIHsNCiAgICAgIGJhc2UgPSBuZXcgQ3RvcihiYXNlKTsNCiAgICAgIGQgPSBiYXNlLmQ7DQoNCiAgICAgIC8vIFJldHVybiBOYU4gaWYgYmFzZSBpcyBuZWdhdGl2ZSwgb3Igbm9uLWZpbml0ZSwgb3IgaXMgMCBvciAxLg0KICAgICAgaWYgKGJhc2UucyA8IDAgfHwgIWQgfHwgIWRbMF0gfHwgYmFzZS5lcSgxKSkgcmV0dXJuIG5ldyBDdG9yKE5hTik7DQoNCiAgICAgIGlzQmFzZTEwID0gYmFzZS5lcSgxMCk7DQogICAgfQ0KDQogICAgZCA9IGFyZy5kOw0KDQogICAgLy8gSXMgYXJnIG5lZ2F0aXZlLCBub24tZmluaXRlLCAwIG9yIDE/DQogICAgaWYgKGFyZy5zIDwgMCB8fCAhZCB8fCAhZFswXSB8fCBhcmcuZXEoMSkpIHsNCiAgICAgIHJldHVybiBuZXcgQ3RvcihkICYmICFkWzBdID8gLTEgLyAwIDogYXJnLnMgIT0gMSA/IE5hTiA6IGQgPyAwIDogMSAvIDApOw0KICAgIH0NCg0KICAgIC8vIFRoZSByZXN1bHQgd2lsbCBoYXZlIGEgbm9uLXRlcm1pbmF0aW5nIGRlY2ltYWwgZXhwYW5zaW9uIGlmIGJhc2UgaXMgMTAgYW5kIGFyZyBpcyBub3QgYW4NCiAgICAvLyBpbnRlZ2VyIHBvd2VyIG9mIDEwLg0KICAgIGlmIChpc0Jhc2UxMCkgew0KICAgICAgaWYgKGQubGVuZ3RoID4gMSkgew0KICAgICAgICBpbmYgPSB0cnVlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgZm9yIChrID0gZFswXTsgayAlIDEwID09PSAwOykgayAvPSAxMDsNCiAgICAgICAgaW5mID0gayAhPT0gMTsNCiAgICAgIH0NCiAgICB9DQoNCiAgICBleHRlcm5hbCA9IGZhbHNlOw0KICAgIHNkID0gcHIgKyBndWFyZDsNCiAgICBudW0gPSBuYXR1cmFsTG9nYXJpdGhtKGFyZywgc2QpOw0KICAgIGRlbm9taW5hdG9yID0gaXNCYXNlMTAgPyBnZXRMbjEwKEN0b3IsIHNkICsgMTApIDogbmF0dXJhbExvZ2FyaXRobShiYXNlLCBzZCk7DQoNCiAgICAvLyBUaGUgcmVzdWx0IHdpbGwgaGF2ZSA1IHJvdW5kaW5nIGRpZ2l0cy4NCiAgICByID0gZGl2aWRlKG51bSwgZGVub21pbmF0b3IsIHNkLCAxKTsNCg0KICAgIC8vIElmIGF0IGEgcm91bmRpbmcgYm91bmRhcnksIGkuZS4gdGhlIHJlc3VsdCdzIHJvdW5kaW5nIGRpZ2l0cyBhcmUgWzQ5XTk5OTkgb3IgWzUwXTAwMDAsDQogICAgLy8gY2FsY3VsYXRlIDEwIGZ1cnRoZXIgZGlnaXRzLg0KICAgIC8vDQogICAgLy8gSWYgdGhlIHJlc3VsdCBpcyBrbm93biB0byBoYXZlIGFuIGluZmluaXRlIGRlY2ltYWwgZXhwYW5zaW9uLCByZXBlYXQgdGhpcyB1bnRpbCBpdCBpcyBjbGVhcg0KICAgIC8vIHRoYXQgdGhlIHJlc3VsdCBpcyBhYm92ZSBvciBiZWxvdyB0aGUgYm91bmRhcnkuIE90aGVyd2lzZSwgaWYgYWZ0ZXIgY2FsY3VsYXRpbmcgdGhlIDEwDQogICAgLy8gZnVydGhlciBkaWdpdHMsIHRoZSBsYXN0IDE0IGFyZSBuaW5lcywgcm91bmQgdXAgYW5kIGFzc3VtZSB0aGUgcmVzdWx0IGlzIGV4YWN0Lg0KICAgIC8vIEFsc28gYXNzdW1lIHRoZSByZXN1bHQgaXMgZXhhY3QgaWYgdGhlIGxhc3QgMTQgYXJlIHplcm8uDQogICAgLy8NCiAgICAvLyBFeGFtcGxlIG9mIGEgcmVzdWx0IHRoYXQgd2lsbCBiZSBpbmNvcnJlY3RseSByb3VuZGVkOg0KICAgIC8vIGxvZ1sxMDQ4NTc2XSg0NTAzNTk5NjI3MzcwNTAyKSA9IDIuNjAwMDAwMDAwMDAwMDAwMDk2MTAyNzk1MTE0NDQ3NDYuLi4NCiAgICAvLyBUaGUgYWJvdmUgcmVzdWx0IGNvcnJlY3RseSByb3VuZGVkIHVzaW5nIFJPVU5EX0NFSUwgdG8gMSBkZWNpbWFsIHBsYWNlIHNob3VsZCBiZSAyLjcsIGJ1dCBpdA0KICAgIC8vIHdpbGwgYmUgZ2l2ZW4gYXMgMi42IGFzIHRoZXJlIGFyZSAxNSB6ZXJvcyBpbW1lZGlhdGVseSBhZnRlciB0aGUgcmVxdWVzdGVkIGRlY2ltYWwgcGxhY2UsIHNvDQogICAgLy8gdGhlIGV4YWN0IHJlc3VsdCB3b3VsZCBiZSBhc3N1bWVkIHRvIGJlIDIuNiwgd2hpY2ggcm91bmRlZCB1c2luZyBST1VORF9DRUlMIHRvIDEgZGVjaW1hbA0KICAgIC8vIHBsYWNlIGlzIHN0aWxsIDIuNi4NCiAgICBpZiAoY2hlY2tSb3VuZGluZ0RpZ2l0cyhyLmQsIGsgPSBwciwgcm0pKSB7DQoNCiAgICAgIGRvIHsNCiAgICAgICAgc2QgKz0gMTA7DQogICAgICAgIG51bSA9IG5hdHVyYWxMb2dhcml0aG0oYXJnLCBzZCk7DQogICAgICAgIGRlbm9taW5hdG9yID0gaXNCYXNlMTAgPyBnZXRMbjEwKEN0b3IsIHNkICsgMTApIDogbmF0dXJhbExvZ2FyaXRobShiYXNlLCBzZCk7DQogICAgICAgIHIgPSBkaXZpZGUobnVtLCBkZW5vbWluYXRvciwgc2QsIDEpOw0KDQogICAgICAgIGlmICghaW5mKSB7DQoNCiAgICAgICAgICAvLyBDaGVjayBmb3IgMTQgbmluZXMgZnJvbSB0aGUgMm5kIHJvdW5kaW5nIGRpZ2l0LCBhcyB0aGUgZmlyc3QgbWF5IGJlIDQuDQogICAgICAgICAgaWYgKCtkaWdpdHNUb1N0cmluZyhyLmQpLnNsaWNlKGsgKyAxLCBrICsgMTUpICsgMSA9PSAxZTE0KSB7DQogICAgICAgICAgICByID0gZmluYWxpc2UociwgcHIgKyAxLCAwKTsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfSB3aGlsZSAoY2hlY2tSb3VuZGluZ0RpZ2l0cyhyLmQsIGsgKz0gMTAsIHJtKSk7DQogICAgfQ0KDQogICAgZXh0ZXJuYWwgPSB0cnVlOw0KDQogICAgcmV0dXJuIGZpbmFsaXNlKHIsIHByLCBybSk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgbWF4aW11bSBvZiB0aGUgYXJndW1lbnRzIGFuZCB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBhcmd1bWVudHMge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9DQogICAqDQogIFAubWF4ID0gZnVuY3Rpb24gKCkgew0KICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmNhbGwoYXJndW1lbnRzLCB0aGlzKTsNCiAgICByZXR1cm4gbWF4T3JNaW4odGhpcy5jb25zdHJ1Y3RvciwgYXJndW1lbnRzLCAtMSk7DQogIH07DQogICAqLw0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG1pbmltdW0gb2YgdGhlIGFyZ3VtZW50cyBhbmQgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbC4NCiAgICoNCiAgICogYXJndW1lbnRzIHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICBQLm1pbiA9IGZ1bmN0aW9uICgpIHsNCiAgICBBcnJheS5wcm90b3R5cGUucHVzaC5jYWxsKGFyZ3VtZW50cywgdGhpcyk7DQogICAgcmV0dXJuIG1heE9yTWluKHRoaXMuY29uc3RydWN0b3IsIGFyZ3VtZW50cywgMSk7DQogIH07DQogICAqLw0KDQoNCiAgLyoNCiAgICogIG4gLSAwID0gbg0KICAgKiAgbiAtIE4gPSBODQogICAqICBuIC0gSSA9IC1JDQogICAqICAwIC0gbiA9IC1uDQogICAqICAwIC0gMCA9IDANCiAgICogIDAgLSBOID0gTg0KICAgKiAgMCAtIEkgPSAtSQ0KICAgKiAgTiAtIG4gPSBODQogICAqICBOIC0gMCA9IE4NCiAgICogIE4gLSBOID0gTg0KICAgKiAgTiAtIEkgPSBODQogICAqICBJIC0gbiA9IEkNCiAgICogIEkgLSAwID0gSQ0KICAgKiAgSSAtIE4gPSBODQogICAqICBJIC0gSSA9IE4NCiAgICoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBtaW51cyBgeWAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICovDQogIFAubWludXMgPSBQLnN1YiA9IGZ1bmN0aW9uICh5KSB7DQogICAgdmFyIGQsIGUsIGksIGosIGssIGxlbiwgcHIsIHJtLCB4ZCwgeGUsIHhMVHksIHlkLA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIHkgPSBuZXcgQ3Rvcih5KTsNCg0KICAgIC8vIElmIGVpdGhlciBpcyBub3QgZmluaXRlLi4uDQogICAgaWYgKCF4LmQgfHwgIXkuZCkgew0KDQogICAgICAvLyBSZXR1cm4gTmFOIGlmIGVpdGhlciBpcyBOYU4uDQogICAgICBpZiAoIXgucyB8fCAheS5zKSB5ID0gbmV3IEN0b3IoTmFOKTsNCg0KICAgICAgLy8gUmV0dXJuIHkgbmVnYXRlZCBpZiB4IGlzIGZpbml0ZSBhbmQgeSBpcyDCsUluZmluaXR5Lg0KICAgICAgZWxzZSBpZiAoeC5kKSB5LnMgPSAteS5zOw0KDQogICAgICAvLyBSZXR1cm4geCBpZiB5IGlzIGZpbml0ZSBhbmQgeCBpcyDCsUluZmluaXR5Lg0KICAgICAgLy8gUmV0dXJuIHggaWYgYm90aCBhcmUgwrFJbmZpbml0eSB3aXRoIGRpZmZlcmVudCBzaWducy4NCiAgICAgIC8vIFJldHVybiBOYU4gaWYgYm90aCBhcmUgwrFJbmZpbml0eSB3aXRoIHRoZSBzYW1lIHNpZ24uDQogICAgICBlbHNlIHkgPSBuZXcgQ3Rvcih5LmQgfHwgeC5zICE9PSB5LnMgPyB4IDogTmFOKTsNCg0KICAgICAgcmV0dXJuIHk7DQogICAgfQ0KDQogICAgLy8gSWYgc2lnbnMgZGlmZmVyLi4uDQogICAgaWYgKHgucyAhPSB5LnMpIHsNCiAgICAgIHkucyA9IC15LnM7DQogICAgICByZXR1cm4geC5wbHVzKHkpOw0KICAgIH0NCg0KICAgIHhkID0geC5kOw0KICAgIHlkID0geS5kOw0KICAgIHByID0gQ3Rvci5wcmVjaXNpb247DQogICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KDQogICAgLy8gSWYgZWl0aGVyIGlzIHplcm8uLi4NCiAgICBpZiAoIXhkWzBdIHx8ICF5ZFswXSkgew0KDQogICAgICAvLyBSZXR1cm4geSBuZWdhdGVkIGlmIHggaXMgemVybyBhbmQgeSBpcyBub24temVyby4NCiAgICAgIGlmICh5ZFswXSkgeS5zID0gLXkuczsNCg0KICAgICAgLy8gUmV0dXJuIHggaWYgeSBpcyB6ZXJvIGFuZCB4IGlzIG5vbi16ZXJvLg0KICAgICAgZWxzZSBpZiAoeGRbMF0pIHkgPSBuZXcgQ3Rvcih4KTsNCg0KICAgICAgLy8gUmV0dXJuIHplcm8gaWYgYm90aCBhcmUgemVyby4NCiAgICAgIC8vIEZyb20gSUVFRSA3NTQgKDIwMDgpIDYuMzogMCAtIDAgPSAtMCAtIC0wID0gLTAgd2hlbiByb3VuZGluZyB0byAtSW5maW5pdHkuDQogICAgICBlbHNlIHJldHVybiBuZXcgQ3RvcihybSA9PT0gMyA/IC0wIDogMCk7DQoNCiAgICAgIHJldHVybiBleHRlcm5hbCA/IGZpbmFsaXNlKHksIHByLCBybSkgOiB5Ow0KICAgIH0NCg0KICAgIC8vIHggYW5kIHkgYXJlIGZpbml0ZSwgbm9uLXplcm8gbnVtYmVycyB3aXRoIHRoZSBzYW1lIHNpZ24uDQoNCiAgICAvLyBDYWxjdWxhdGUgYmFzZSAxZTcgZXhwb25lbnRzLg0KICAgIGUgPSBtYXRoZmxvb3IoeS5lIC8gTE9HX0JBU0UpOw0KICAgIHhlID0gbWF0aGZsb29yKHguZSAvIExPR19CQVNFKTsNCg0KICAgIHhkID0geGQuc2xpY2UoKTsNCiAgICBrID0geGUgLSBlOw0KDQogICAgLy8gSWYgYmFzZSAxZTcgZXhwb25lbnRzIGRpZmZlci4uLg0KICAgIGlmIChrKSB7DQogICAgICB4TFR5ID0gayA8IDA7DQoNCiAgICAgIGlmICh4TFR5KSB7DQogICAgICAgIGQgPSB4ZDsNCiAgICAgICAgayA9IC1rOw0KICAgICAgICBsZW4gPSB5ZC5sZW5ndGg7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBkID0geWQ7DQogICAgICAgIGUgPSB4ZTsNCiAgICAgICAgbGVuID0geGQubGVuZ3RoOw0KICAgICAgfQ0KDQogICAgICAvLyBOdW1iZXJzIHdpdGggbWFzc2l2ZWx5IGRpZmZlcmVudCBleHBvbmVudHMgd291bGQgcmVzdWx0IGluIGEgdmVyeSBoaWdoIG51bWJlciBvZg0KICAgICAgLy8gemVyb3MgbmVlZGluZyB0byBiZSBwcmVwZW5kZWQsIGJ1dCB0aGlzIGNhbiBiZSBhdm9pZGVkIHdoaWxlIHN0aWxsIGVuc3VyaW5nIGNvcnJlY3QNCiAgICAgIC8vIHJvdW5kaW5nIGJ5IGxpbWl0aW5nIHRoZSBudW1iZXIgb2YgemVyb3MgdG8gYE1hdGguY2VpbChwciAvIExPR19CQVNFKSArIDJgLg0KICAgICAgaSA9IE1hdGgubWF4KE1hdGguY2VpbChwciAvIExPR19CQVNFKSwgbGVuKSArIDI7DQoNCiAgICAgIGlmIChrID4gaSkgew0KICAgICAgICBrID0gaTsNCiAgICAgICAgZC5sZW5ndGggPSAxOw0KICAgICAgfQ0KDQogICAgICAvLyBQcmVwZW5kIHplcm9zIHRvIGVxdWFsaXNlIGV4cG9uZW50cy4NCiAgICAgIGQucmV2ZXJzZSgpOw0KICAgICAgZm9yIChpID0gazsgaS0tOykgZC5wdXNoKDApOw0KICAgICAgZC5yZXZlcnNlKCk7DQoNCiAgICAvLyBCYXNlIDFlNyBleHBvbmVudHMgZXF1YWwuDQogICAgfSBlbHNlIHsNCg0KICAgICAgLy8gQ2hlY2sgZGlnaXRzIHRvIGRldGVybWluZSB3aGljaCBpcyB0aGUgYmlnZ2VyIG51bWJlci4NCg0KICAgICAgaSA9IHhkLmxlbmd0aDsNCiAgICAgIGxlbiA9IHlkLmxlbmd0aDsNCiAgICAgIHhMVHkgPSBpIDwgbGVuOw0KICAgICAgaWYgKHhMVHkpIGxlbiA9IGk7DQoNCiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgew0KICAgICAgICBpZiAoeGRbaV0gIT0geWRbaV0pIHsNCiAgICAgICAgICB4TFR5ID0geGRbaV0gPCB5ZFtpXTsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfQ0KDQogICAgICBrID0gMDsNCiAgICB9DQoNCiAgICBpZiAoeExUeSkgew0KICAgICAgZCA9IHhkOw0KICAgICAgeGQgPSB5ZDsNCiAgICAgIHlkID0gZDsNCiAgICAgIHkucyA9IC15LnM7DQogICAgfQ0KDQogICAgbGVuID0geGQubGVuZ3RoOw0KDQogICAgLy8gQXBwZW5kIHplcm9zIHRvIGB4ZGAgaWYgc2hvcnRlci4NCiAgICAvLyBEb24ndCBhZGQgemVyb3MgdG8gYHlkYCBpZiBzaG9ydGVyIGFzIHN1YnRyYWN0aW9uIG9ubHkgbmVlZHMgdG8gc3RhcnQgYXQgYHlkYCBsZW5ndGguDQogICAgZm9yIChpID0geWQubGVuZ3RoIC0gbGVuOyBpID4gMDsgLS1pKSB4ZFtsZW4rK10gPSAwOw0KDQogICAgLy8gU3VidHJhY3QgeWQgZnJvbSB4ZC4NCiAgICBmb3IgKGkgPSB5ZC5sZW5ndGg7IGkgPiBrOykgew0KDQogICAgICBpZiAoeGRbLS1pXSA8IHlkW2ldKSB7DQogICAgICAgIGZvciAoaiA9IGk7IGogJiYgeGRbLS1qXSA9PT0gMDspIHhkW2pdID0gQkFTRSAtIDE7DQogICAgICAgIC0teGRbal07DQogICAgICAgIHhkW2ldICs9IEJBU0U7DQogICAgICB9DQoNCiAgICAgIHhkW2ldIC09IHlkW2ldOw0KICAgIH0NCg0KICAgIC8vIFJlbW92ZSB0cmFpbGluZyB6ZXJvcy4NCiAgICBmb3IgKDsgeGRbLS1sZW5dID09PSAwOykgeGQucG9wKCk7DQoNCiAgICAvLyBSZW1vdmUgbGVhZGluZyB6ZXJvcyBhbmQgYWRqdXN0IGV4cG9uZW50IGFjY29yZGluZ2x5Lg0KICAgIGZvciAoOyB4ZFswXSA9PT0gMDsgeGQuc2hpZnQoKSkgLS1lOw0KDQogICAgLy8gWmVybz8NCiAgICBpZiAoIXhkWzBdKSByZXR1cm4gbmV3IEN0b3Iocm0gPT09IDMgPyAtMCA6IDApOw0KDQogICAgeS5kID0geGQ7DQogICAgeS5lID0gZ2V0QmFzZTEwRXhwb25lbnQoeGQsIGUpOw0KDQogICAgcmV0dXJuIGV4dGVybmFsID8gZmluYWxpc2UoeSwgcHIsIHJtKSA6IHk7DQogIH07DQoNCg0KICAvKg0KICAgKiAgIG4gJSAwID0gIE4NCiAgICogICBuICUgTiA9ICBODQogICAqICAgbiAlIEkgPSAgbg0KICAgKiAgIDAgJSBuID0gIDANCiAgICogIC0wICUgbiA9IC0wDQogICAqICAgMCAlIDAgPSAgTg0KICAgKiAgIDAgJSBOID0gIE4NCiAgICogICAwICUgSSA9ICAwDQogICAqICAgTiAlIG4gPSAgTg0KICAgKiAgIE4gJSAwID0gIE4NCiAgICogICBOICUgTiA9ICBODQogICAqICAgTiAlIEkgPSAgTg0KICAgKiAgIEkgJSBuID0gIE4NCiAgICogICBJICUgMCA9ICBODQogICAqICAgSSAlIE4gPSAgTg0KICAgKiAgIEkgJSBJID0gIE4NCiAgICoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBtb2R1bG8gYHlgLCByb3VuZGVkIHRvDQogICAqIGBwcmVjaXNpb25gIHNpZ25pZmljYW50IGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqIFRoZSByZXN1bHQgZGVwZW5kcyBvbiB0aGUgbW9kdWxvIG1vZGUuDQogICAqDQogICAqLw0KICBQLm1vZHVsbyA9IFAubW9kID0gZnVuY3Rpb24gKHkpIHsNCiAgICB2YXIgcSwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICB5ID0gbmV3IEN0b3IoeSk7DQoNCiAgICAvLyBSZXR1cm4gTmFOIGlmIHggaXMgwrFJbmZpbml0eSBvciBOYU4sIG9yIHkgaXMgTmFOIG9yIMKxMC4NCiAgICBpZiAoIXguZCB8fCAheS5zIHx8IHkuZCAmJiAheS5kWzBdKSByZXR1cm4gbmV3IEN0b3IoTmFOKTsNCg0KICAgIC8vIFJldHVybiB4IGlmIHkgaXMgwrFJbmZpbml0eSBvciB4IGlzIMKxMC4NCiAgICBpZiAoIXkuZCB8fCB4LmQgJiYgIXguZFswXSkgew0KICAgICAgcmV0dXJuIGZpbmFsaXNlKG5ldyBDdG9yKHgpLCBDdG9yLnByZWNpc2lvbiwgQ3Rvci5yb3VuZGluZyk7DQogICAgfQ0KDQogICAgLy8gUHJldmVudCByb3VuZGluZyBvZiBpbnRlcm1lZGlhdGUgY2FsY3VsYXRpb25zLg0KICAgIGV4dGVybmFsID0gZmFsc2U7DQoNCiAgICBpZiAoQ3Rvci5tb2R1bG8gPT0gOSkgew0KDQogICAgICAvLyBFdWNsaWRpYW4gZGl2aXNpb246IHEgPSBzaWduKHkpICogZmxvb3IoeCAvIGFicyh5KSkNCiAgICAgIC8vIHJlc3VsdCA9IHggLSBxICogeSAgICB3aGVyZSAgMCA8PSByZXN1bHQgPCBhYnMoeSkNCiAgICAgIHEgPSBkaXZpZGUoeCwgeS5hYnMoKSwgMCwgMywgMSk7DQogICAgICBxLnMgKj0geS5zOw0KICAgIH0gZWxzZSB7DQogICAgICBxID0gZGl2aWRlKHgsIHksIDAsIEN0b3IubW9kdWxvLCAxKTsNCiAgICB9DQoNCiAgICBxID0gcS50aW1lcyh5KTsNCg0KICAgIGV4dGVybmFsID0gdHJ1ZTsNCg0KICAgIHJldHVybiB4Lm1pbnVzKHEpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG5hdHVyYWwgZXhwb25lbnRpYWwgb2YgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCwNCiAgICogaS5lLiB0aGUgYmFzZSBlIHJhaXNlZCB0byB0aGUgcG93ZXIgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYA0KICAgKiBzaWduaWZpY2FudCBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKi8NCiAgUC5uYXR1cmFsRXhwb25lbnRpYWwgPSBQLmV4cCA9IGZ1bmN0aW9uICgpIHsNCiAgICByZXR1cm4gbmF0dXJhbEV4cG9uZW50aWFsKHRoaXMpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwsDQogICAqIHJvdW5kZWQgdG8gYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICovDQogIFAubmF0dXJhbExvZ2FyaXRobSA9IFAubG4gPSBmdW5jdGlvbiAoKSB7DQogICAgcmV0dXJuIG5hdHVyYWxMb2dhcml0aG0odGhpcyk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIG5lZ2F0ZWQsIGkuZS4gYXMgaWYgbXVsdGlwbGllZCBieQ0KICAgKiAtMS4NCiAgICoNCiAgICovDQogIFAubmVnYXRlZCA9IFAubmVnID0gZnVuY3Rpb24gKCkgew0KICAgIHZhciB4ID0gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcyk7DQogICAgeC5zID0gLXguczsNCiAgICByZXR1cm4gZmluYWxpc2UoeCk7DQogIH07DQoNCg0KICAvKg0KICAgKiAgbiArIDAgPSBuDQogICAqICBuICsgTiA9IE4NCiAgICogIG4gKyBJID0gSQ0KICAgKiAgMCArIG4gPSBuDQogICAqICAwICsgMCA9IDANCiAgICogIDAgKyBOID0gTg0KICAgKiAgMCArIEkgPSBJDQogICAqICBOICsgbiA9IE4NCiAgICogIE4gKyAwID0gTg0KICAgKiAgTiArIE4gPSBODQogICAqICBOICsgSSA9IE4NCiAgICogIEkgKyBuID0gSQ0KICAgKiAgSSArIDAgPSBJDQogICAqICBJICsgTiA9IE4NCiAgICogIEkgKyBJID0gSQ0KICAgKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIHBsdXMgYHlgLCByb3VuZGVkIHRvIGBwcmVjaXNpb25gDQogICAqIHNpZ25pZmljYW50IGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqLw0KICBQLnBsdXMgPSBQLmFkZCA9IGZ1bmN0aW9uICh5KSB7DQogICAgdmFyIGNhcnJ5LCBkLCBlLCBpLCBrLCBsZW4sIHByLCBybSwgeGQsIHlkLA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIHkgPSBuZXcgQ3Rvcih5KTsNCg0KICAgIC8vIElmIGVpdGhlciBpcyBub3QgZmluaXRlLi4uDQogICAgaWYgKCF4LmQgfHwgIXkuZCkgew0KDQogICAgICAvLyBSZXR1cm4gTmFOIGlmIGVpdGhlciBpcyBOYU4uDQogICAgICBpZiAoIXgucyB8fCAheS5zKSB5ID0gbmV3IEN0b3IoTmFOKTsNCg0KICAgICAgLy8gUmV0dXJuIHggaWYgeSBpcyBmaW5pdGUgYW5kIHggaXMgwrFJbmZpbml0eS4NCiAgICAgIC8vIFJldHVybiB4IGlmIGJvdGggYXJlIMKxSW5maW5pdHkgd2l0aCB0aGUgc2FtZSBzaWduLg0KICAgICAgLy8gUmV0dXJuIE5hTiBpZiBib3RoIGFyZSDCsUluZmluaXR5IHdpdGggZGlmZmVyZW50IHNpZ25zLg0KICAgICAgLy8gUmV0dXJuIHkgaWYgeCBpcyBmaW5pdGUgYW5kIHkgaXMgwrFJbmZpbml0eS4NCiAgICAgIGVsc2UgaWYgKCF4LmQpIHkgPSBuZXcgQ3Rvcih5LmQgfHwgeC5zID09PSB5LnMgPyB4IDogTmFOKTsNCg0KICAgICAgcmV0dXJuIHk7DQogICAgfQ0KDQogICAgIC8vIElmIHNpZ25zIGRpZmZlci4uLg0KICAgIGlmICh4LnMgIT0geS5zKSB7DQogICAgICB5LnMgPSAteS5zOw0KICAgICAgcmV0dXJuIHgubWludXMoeSk7DQogICAgfQ0KDQogICAgeGQgPSB4LmQ7DQogICAgeWQgPSB5LmQ7DQogICAgcHIgPSBDdG9yLnByZWNpc2lvbjsNCiAgICBybSA9IEN0b3Iucm91bmRpbmc7DQoNCiAgICAvLyBJZiBlaXRoZXIgaXMgemVyby4uLg0KICAgIGlmICgheGRbMF0gfHwgIXlkWzBdKSB7DQoNCiAgICAgIC8vIFJldHVybiB4IGlmIHkgaXMgemVyby4NCiAgICAgIC8vIFJldHVybiB5IGlmIHkgaXMgbm9uLXplcm8uDQogICAgICBpZiAoIXlkWzBdKSB5ID0gbmV3IEN0b3IoeCk7DQoNCiAgICAgIHJldHVybiBleHRlcm5hbCA/IGZpbmFsaXNlKHksIHByLCBybSkgOiB5Ow0KICAgIH0NCg0KICAgIC8vIHggYW5kIHkgYXJlIGZpbml0ZSwgbm9uLXplcm8gbnVtYmVycyB3aXRoIHRoZSBzYW1lIHNpZ24uDQoNCiAgICAvLyBDYWxjdWxhdGUgYmFzZSAxZTcgZXhwb25lbnRzLg0KICAgIGsgPSBtYXRoZmxvb3IoeC5lIC8gTE9HX0JBU0UpOw0KICAgIGUgPSBtYXRoZmxvb3IoeS5lIC8gTE9HX0JBU0UpOw0KDQogICAgeGQgPSB4ZC5zbGljZSgpOw0KICAgIGkgPSBrIC0gZTsNCg0KICAgIC8vIElmIGJhc2UgMWU3IGV4cG9uZW50cyBkaWZmZXIuLi4NCiAgICBpZiAoaSkgew0KDQogICAgICBpZiAoaSA8IDApIHsNCiAgICAgICAgZCA9IHhkOw0KICAgICAgICBpID0gLWk7DQogICAgICAgIGxlbiA9IHlkLmxlbmd0aDsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGQgPSB5ZDsNCiAgICAgICAgZSA9IGs7DQogICAgICAgIGxlbiA9IHhkLmxlbmd0aDsNCiAgICAgIH0NCg0KICAgICAgLy8gTGltaXQgbnVtYmVyIG9mIHplcm9zIHByZXBlbmRlZCB0byBtYXgoY2VpbChwciAvIExPR19CQVNFKSwgbGVuKSArIDEuDQogICAgICBrID0gTWF0aC5jZWlsKHByIC8gTE9HX0JBU0UpOw0KICAgICAgbGVuID0gayA+IGxlbiA/IGsgKyAxIDogbGVuICsgMTsNCg0KICAgICAgaWYgKGkgPiBsZW4pIHsNCiAgICAgICAgaSA9IGxlbjsNCiAgICAgICAgZC5sZW5ndGggPSAxOw0KICAgICAgfQ0KDQogICAgICAvLyBQcmVwZW5kIHplcm9zIHRvIGVxdWFsaXNlIGV4cG9uZW50cy4gTm90ZTogRmFzdGVyIHRvIHVzZSByZXZlcnNlIHRoZW4gZG8gdW5zaGlmdHMuDQogICAgICBkLnJldmVyc2UoKTsNCiAgICAgIGZvciAoOyBpLS07KSBkLnB1c2goMCk7DQogICAgICBkLnJldmVyc2UoKTsNCiAgICB9DQoNCiAgICBsZW4gPSB4ZC5sZW5ndGg7DQogICAgaSA9IHlkLmxlbmd0aDsNCg0KICAgIC8vIElmIHlkIGlzIGxvbmdlciB0aGFuIHhkLCBzd2FwIHhkIGFuZCB5ZCBzbyB4ZCBwb2ludHMgdG8gdGhlIGxvbmdlciBhcnJheS4NCiAgICBpZiAobGVuIC0gaSA8IDApIHsNCiAgICAgIGkgPSBsZW47DQogICAgICBkID0geWQ7DQogICAgICB5ZCA9IHhkOw0KICAgICAgeGQgPSBkOw0KICAgIH0NCg0KICAgIC8vIE9ubHkgc3RhcnQgYWRkaW5nIGF0IHlkLmxlbmd0aCAtIDEgYXMgdGhlIGZ1cnRoZXIgZGlnaXRzIG9mIHhkIGNhbiBiZSBsZWZ0IGFzIHRoZXkgYXJlLg0KICAgIGZvciAoY2FycnkgPSAwOyBpOykgew0KICAgICAgY2FycnkgPSAoeGRbLS1pXSA9IHhkW2ldICsgeWRbaV0gKyBjYXJyeSkgLyBCQVNFIHwgMDsNCiAgICAgIHhkW2ldICU9IEJBU0U7DQogICAgfQ0KDQogICAgaWYgKGNhcnJ5KSB7DQogICAgICB4ZC51bnNoaWZ0KGNhcnJ5KTsNCiAgICAgICsrZTsNCiAgICB9DQoNCiAgICAvLyBSZW1vdmUgdHJhaWxpbmcgemVyb3MuDQogICAgLy8gTm8gbmVlZCB0byBjaGVjayBmb3IgemVybywgYXMgK3ggKyAreSAhPSAwICYmIC14ICsgLXkgIT0gMA0KICAgIGZvciAobGVuID0geGQubGVuZ3RoOyB4ZFstLWxlbl0gPT0gMDspIHhkLnBvcCgpOw0KDQogICAgeS5kID0geGQ7DQogICAgeS5lID0gZ2V0QmFzZTEwRXhwb25lbnQoeGQsIGUpOw0KDQogICAgcmV0dXJuIGV4dGVybmFsID8gZmluYWxpc2UoeSwgcHIsIHJtKSA6IHk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBkaWdpdHMgb2YgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbC4NCiAgICoNCiAgICogW3pdIHtib29sZWFufG51bWJlcn0gV2hldGhlciB0byBjb3VudCBpbnRlZ2VyLXBhcnQgdHJhaWxpbmcgemVyb3M6IHRydWUsIGZhbHNlLCAxIG9yIDAuDQogICAqDQogICAqLw0KICBQLnByZWNpc2lvbiA9IFAuc2QgPSBmdW5jdGlvbiAoeikgew0KICAgIHZhciBrLA0KICAgICAgeCA9IHRoaXM7DQoNCiAgICBpZiAoeiAhPT0gdm9pZCAwICYmIHogIT09ICEheiAmJiB6ICE9PSAxICYmIHogIT09IDApIHRocm93IEVycm9yKGludmFsaWRBcmd1bWVudCArIHopOw0KDQogICAgaWYgKHguZCkgew0KICAgICAgayA9IGdldFByZWNpc2lvbih4LmQpOw0KICAgICAgaWYgKHogJiYgeC5lICsgMSA+IGspIGsgPSB4LmUgKyAxOw0KICAgIH0gZWxzZSB7DQogICAgICBrID0gTmFOOw0KICAgIH0NCg0KICAgIHJldHVybiBrOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCByb3VuZGVkIHRvIGEgd2hvbGUgbnVtYmVyIHVzaW5nDQogICAqIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICovDQogIFAucm91bmQgPSBmdW5jdGlvbiAoKSB7DQogICAgdmFyIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICByZXR1cm4gZmluYWxpc2UobmV3IEN0b3IoeCksIHguZSArIDEsIEN0b3Iucm91bmRpbmcpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHNpbmUgb2YgdGhlIHZhbHVlIGluIHJhZGlhbnMgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWy0xLCAxXQ0KICAgKg0KICAgKiBzaW4oeCkgPSB4IC0geF4zLzMhICsgeF41LzUhIC0gLi4uDQogICAqDQogICAqIHNpbigwKSAgICAgICAgID0gMA0KICAgKiBzaW4oLTApICAgICAgICA9IC0wDQogICAqIHNpbihJbmZpbml0eSkgID0gTmFODQogICAqIHNpbigtSW5maW5pdHkpID0gTmFODQogICAqIHNpbihOYU4pICAgICAgID0gTmFODQogICAqDQogICAqLw0KICBQLnNpbmUgPSBQLnNpbiA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgcHIsIHJtLA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmICgheC5pc0Zpbml0ZSgpKSByZXR1cm4gbmV3IEN0b3IoTmFOKTsNCiAgICBpZiAoeC5pc1plcm8oKSkgcmV0dXJuIG5ldyBDdG9yKHgpOw0KDQogICAgcHIgPSBDdG9yLnByZWNpc2lvbjsNCiAgICBybSA9IEN0b3Iucm91bmRpbmc7DQogICAgQ3Rvci5wcmVjaXNpb24gPSBwciArIE1hdGgubWF4KHguZSwgeC5zZCgpKSArIExPR19CQVNFOw0KICAgIEN0b3Iucm91bmRpbmcgPSAxOw0KDQogICAgeCA9IHNpbmUoQ3RvciwgdG9MZXNzVGhhbkhhbGZQaShDdG9yLCB4KSk7DQoNCiAgICBDdG9yLnByZWNpc2lvbiA9IHByOw0KICAgIEN0b3Iucm91bmRpbmcgPSBybTsNCg0KICAgIHJldHVybiBmaW5hbGlzZShxdWFkcmFudCA+IDIgPyB4Lm5lZygpIDogeCwgcHIsIHJtLCB0cnVlKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBzcXVhcmUgcm9vdCBvZiB0aGlzIERlY2ltYWwsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogIHNxcnQoLW4pID0gIE4NCiAgICogIHNxcnQoTikgID0gIE4NCiAgICogIHNxcnQoLUkpID0gIE4NCiAgICogIHNxcnQoSSkgID0gIEkNCiAgICogIHNxcnQoMCkgID0gIDANCiAgICogIHNxcnQoLTApID0gLTANCiAgICoNCiAgICovDQogIFAuc3F1YXJlUm9vdCA9IFAuc3FydCA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgbSwgbiwgc2QsIHIsIHJlcCwgdCwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgZCA9IHguZCwNCiAgICAgIGUgPSB4LmUsDQogICAgICBzID0geC5zLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICAvLyBOZWdhdGl2ZS9OYU4vSW5maW5pdHkvemVybz8NCiAgICBpZiAocyAhPT0gMSB8fCAhZCB8fCAhZFswXSkgew0KICAgICAgcmV0dXJuIG5ldyBDdG9yKCFzIHx8IHMgPCAwICYmICghZCB8fCBkWzBdKSA/IE5hTiA6IGQgPyB4IDogMSAvIDApOw0KICAgIH0NCg0KICAgIGV4dGVybmFsID0gZmFsc2U7DQoNCiAgICAvLyBJbml0aWFsIGVzdGltYXRlLg0KICAgIHMgPSBNYXRoLnNxcnQoK3gpOw0KDQogICAgLy8gTWF0aC5zcXJ0IHVuZGVyZmxvdy9vdmVyZmxvdz8NCiAgICAvLyBQYXNzIHggdG8gTWF0aC5zcXJ0IGFzIGludGVnZXIsIHRoZW4gYWRqdXN0IHRoZSBleHBvbmVudCBvZiB0aGUgcmVzdWx0Lg0KICAgIGlmIChzID09IDAgfHwgcyA9PSAxIC8gMCkgew0KICAgICAgbiA9IGRpZ2l0c1RvU3RyaW5nKGQpOw0KDQogICAgICBpZiAoKG4ubGVuZ3RoICsgZSkgJSAyID09IDApIG4gKz0gJzAnOw0KICAgICAgcyA9IE1hdGguc3FydChuKTsNCiAgICAgIGUgPSBtYXRoZmxvb3IoKGUgKyAxKSAvIDIpIC0gKGUgPCAwIHx8IGUgJSAyKTsNCg0KICAgICAgaWYgKHMgPT0gMSAvIDApIHsNCiAgICAgICAgbiA9ICc1ZScgKyBlOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbiA9IHMudG9FeHBvbmVudGlhbCgpOw0KICAgICAgICBuID0gbi5zbGljZSgwLCBuLmluZGV4T2YoJ2UnKSArIDEpICsgZTsNCiAgICAgIH0NCg0KICAgICAgciA9IG5ldyBDdG9yKG4pOw0KICAgIH0gZWxzZSB7DQogICAgICByID0gbmV3IEN0b3Iocy50b1N0cmluZygpKTsNCiAgICB9DQoNCiAgICBzZCA9IChlID0gQ3Rvci5wcmVjaXNpb24pICsgMzsNCg0KICAgIC8vIE5ld3Rvbi1SYXBoc29uIGl0ZXJhdGlvbi4NCiAgICBmb3IgKDs7KSB7DQogICAgICB0ID0gcjsNCiAgICAgIHIgPSB0LnBsdXMoZGl2aWRlKHgsIHQsIHNkICsgMiwgMSkpLnRpbWVzKDAuNSk7DQoNCiAgICAgIC8vIFRPRE8/IFJlcGxhY2Ugd2l0aCBmb3ItbG9vcCBhbmQgY2hlY2tSb3VuZGluZ0RpZ2l0cy4NCiAgICAgIGlmIChkaWdpdHNUb1N0cmluZyh0LmQpLnNsaWNlKDAsIHNkKSA9PT0gKG4gPSBkaWdpdHNUb1N0cmluZyhyLmQpKS5zbGljZSgwLCBzZCkpIHsNCiAgICAgICAgbiA9IG4uc2xpY2Uoc2QgLSAzLCBzZCArIDEpOw0KDQogICAgICAgIC8vIFRoZSA0dGggcm91bmRpbmcgZGlnaXQgbWF5IGJlIGluIGVycm9yIGJ5IC0xIHNvIGlmIHRoZSA0IHJvdW5kaW5nIGRpZ2l0cyBhcmUgOTk5OSBvcg0KICAgICAgICAvLyA0OTk5LCBpLmUuIGFwcHJvYWNoaW5nIGEgcm91bmRpbmcgYm91bmRhcnksIGNvbnRpbnVlIHRoZSBpdGVyYXRpb24uDQogICAgICAgIGlmIChuID09ICc5OTk5JyB8fCAhcmVwICYmIG4gPT0gJzQ5OTknKSB7DQoNCiAgICAgICAgICAvLyBPbiB0aGUgZmlyc3QgaXRlcmF0aW9uIG9ubHksIGNoZWNrIHRvIHNlZSBpZiByb3VuZGluZyB1cCBnaXZlcyB0aGUgZXhhY3QgcmVzdWx0IGFzIHRoZQ0KICAgICAgICAgIC8vIG5pbmVzIG1heSBpbmZpbml0ZWx5IHJlcGVhdC4NCiAgICAgICAgICBpZiAoIXJlcCkgew0KICAgICAgICAgICAgZmluYWxpc2UodCwgZSArIDEsIDApOw0KDQogICAgICAgICAgICBpZiAodC50aW1lcyh0KS5lcSh4KSkgew0KICAgICAgICAgICAgICByID0gdDsNCiAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KDQogICAgICAgICAgc2QgKz0gNDsNCiAgICAgICAgICByZXAgPSAxOw0KICAgICAgICB9IGVsc2Ugew0KDQogICAgICAgICAgLy8gSWYgdGhlIHJvdW5kaW5nIGRpZ2l0cyBhcmUgbnVsbCwgMHswLDR9IG9yIDUwezAsM30sIGNoZWNrIGZvciBhbiBleGFjdCByZXN1bHQuDQogICAgICAgICAgLy8gSWYgbm90LCB0aGVuIHRoZXJlIGFyZSBmdXJ0aGVyIGRpZ2l0cyBhbmQgbSB3aWxsIGJlIHRydXRoeS4NCiAgICAgICAgICBpZiAoIStuIHx8ICErbi5zbGljZSgxKSAmJiBuLmNoYXJBdCgwKSA9PSAnNScpIHsNCg0KICAgICAgICAgICAgLy8gVHJ1bmNhdGUgdG8gdGhlIGZpcnN0IHJvdW5kaW5nIGRpZ2l0Lg0KICAgICAgICAgICAgZmluYWxpc2UociwgZSArIDEsIDEpOw0KICAgICAgICAgICAgbSA9ICFyLnRpbWVzKHIpLmVxKHgpOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KDQogICAgZXh0ZXJuYWwgPSB0cnVlOw0KDQogICAgcmV0dXJuIGZpbmFsaXNlKHIsIGUsIEN0b3Iucm91bmRpbmcsIG0pOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHRhbmdlbnQgb2YgdGhlIHZhbHVlIGluIHJhZGlhbnMgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBEb21haW46IFstSW5maW5pdHksIEluZmluaXR5XQ0KICAgKiBSYW5nZTogWy1JbmZpbml0eSwgSW5maW5pdHldDQogICAqDQogICAqIHRhbigwKSAgICAgICAgID0gMA0KICAgKiB0YW4oLTApICAgICAgICA9IC0wDQogICAqIHRhbihJbmZpbml0eSkgID0gTmFODQogICAqIHRhbigtSW5maW5pdHkpID0gTmFODQogICAqIHRhbihOYU4pICAgICAgID0gTmFODQogICAqDQogICAqLw0KICBQLnRhbmdlbnQgPSBQLnRhbiA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgcHIsIHJtLA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmICgheC5pc0Zpbml0ZSgpKSByZXR1cm4gbmV3IEN0b3IoTmFOKTsNCiAgICBpZiAoeC5pc1plcm8oKSkgcmV0dXJuIG5ldyBDdG9yKHgpOw0KDQogICAgcHIgPSBDdG9yLnByZWNpc2lvbjsNCiAgICBybSA9IEN0b3Iucm91bmRpbmc7DQogICAgQ3Rvci5wcmVjaXNpb24gPSBwciArIDEwOw0KICAgIEN0b3Iucm91bmRpbmcgPSAxOw0KDQogICAgeCA9IHguc2luKCk7DQogICAgeC5zID0gMTsNCiAgICB4ID0gZGl2aWRlKHgsIG5ldyBDdG9yKDEpLm1pbnVzKHgudGltZXMoeCkpLnNxcnQoKSwgcHIgKyAxMCwgMCk7DQoNCiAgICBDdG9yLnByZWNpc2lvbiA9IHByOw0KICAgIEN0b3Iucm91bmRpbmcgPSBybTsNCg0KICAgIHJldHVybiBmaW5hbGlzZShxdWFkcmFudCA9PSAyIHx8IHF1YWRyYW50ID09IDQgPyB4Lm5lZygpIDogeCwgcHIsIHJtLCB0cnVlKTsNCiAgfTsNCg0KDQogIC8qDQogICAqICBuICogMCA9IDANCiAgICogIG4gKiBOID0gTg0KICAgKiAgbiAqIEkgPSBJDQogICAqICAwICogbiA9IDANCiAgICogIDAgKiAwID0gMA0KICAgKiAgMCAqIE4gPSBODQogICAqICAwICogSSA9IE4NCiAgICogIE4gKiBuID0gTg0KICAgKiAgTiAqIDAgPSBODQogICAqICBOICogTiA9IE4NCiAgICogIE4gKiBJID0gTg0KICAgKiAgSSAqIG4gPSBJDQogICAqICBJICogMCA9IE4NCiAgICogIEkgKiBOID0gTg0KICAgKiAgSSAqIEkgPSBJDQogICAqDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoaXMgRGVjaW1hbCB0aW1lcyBgeWAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQNCiAgICogZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICovDQogIFAudGltZXMgPSBQLm11bCA9IGZ1bmN0aW9uICh5KSB7DQogICAgdmFyIGNhcnJ5LCBlLCBpLCBrLCByLCByTCwgdCwgeGRMLCB5ZEwsDQogICAgICB4ID0gdGhpcywNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yLA0KICAgICAgeGQgPSB4LmQsDQogICAgICB5ZCA9ICh5ID0gbmV3IEN0b3IoeSkpLmQ7DQoNCiAgICB5LnMgKj0geC5zOw0KDQogICAgIC8vIElmIGVpdGhlciBpcyBOYU4sIMKxSW5maW5pdHkgb3IgwrEwLi4uDQogICAgaWYgKCF4ZCB8fCAheGRbMF0gfHwgIXlkIHx8ICF5ZFswXSkgew0KDQogICAgICByZXR1cm4gbmV3IEN0b3IoIXkucyB8fCB4ZCAmJiAheGRbMF0gJiYgIXlkIHx8IHlkICYmICF5ZFswXSAmJiAheGQNCg0KICAgICAgICAvLyBSZXR1cm4gTmFOIGlmIGVpdGhlciBpcyBOYU4uDQogICAgICAgIC8vIFJldHVybiBOYU4gaWYgeCBpcyDCsTAgYW5kIHkgaXMgwrFJbmZpbml0eSwgb3IgeSBpcyDCsTAgYW5kIHggaXMgwrFJbmZpbml0eS4NCiAgICAgICAgPyBOYU4NCg0KICAgICAgICAvLyBSZXR1cm4gwrFJbmZpbml0eSBpZiBlaXRoZXIgaXMgwrFJbmZpbml0eS4NCiAgICAgICAgLy8gUmV0dXJuIMKxMCBpZiBlaXRoZXIgaXMgwrEwLg0KICAgICAgICA6ICF4ZCB8fCAheWQgPyB5LnMgLyAwIDogeS5zICogMCk7DQogICAgfQ0KDQogICAgZSA9IG1hdGhmbG9vcih4LmUgLyBMT0dfQkFTRSkgKyBtYXRoZmxvb3IoeS5lIC8gTE9HX0JBU0UpOw0KICAgIHhkTCA9IHhkLmxlbmd0aDsNCiAgICB5ZEwgPSB5ZC5sZW5ndGg7DQoNCiAgICAvLyBFbnN1cmUgeGQgcG9pbnRzIHRvIHRoZSBsb25nZXIgYXJyYXkuDQogICAgaWYgKHhkTCA8IHlkTCkgew0KICAgICAgciA9IHhkOw0KICAgICAgeGQgPSB5ZDsNCiAgICAgIHlkID0gcjsNCiAgICAgIHJMID0geGRMOw0KICAgICAgeGRMID0geWRMOw0KICAgICAgeWRMID0gckw7DQogICAgfQ0KDQogICAgLy8gSW5pdGlhbGlzZSB0aGUgcmVzdWx0IGFycmF5IHdpdGggemVyb3MuDQogICAgciA9IFtdOw0KICAgIHJMID0geGRMICsgeWRMOw0KICAgIGZvciAoaSA9IHJMOyBpLS07KSByLnB1c2goMCk7DQoNCiAgICAvLyBNdWx0aXBseSENCiAgICBmb3IgKGkgPSB5ZEw7IC0taSA+PSAwOykgew0KICAgICAgY2FycnkgPSAwOw0KICAgICAgZm9yIChrID0geGRMICsgaTsgayA+IGk7KSB7DQogICAgICAgIHQgPSByW2tdICsgeWRbaV0gKiB4ZFtrIC0gaSAtIDFdICsgY2Fycnk7DQogICAgICAgIHJbay0tXSA9IHQgJSBCQVNFIHwgMDsNCiAgICAgICAgY2FycnkgPSB0IC8gQkFTRSB8IDA7DQogICAgICB9DQoNCiAgICAgIHJba10gPSAocltrXSArIGNhcnJ5KSAlIEJBU0UgfCAwOw0KICAgIH0NCg0KICAgIC8vIFJlbW92ZSB0cmFpbGluZyB6ZXJvcy4NCiAgICBmb3IgKDsgIXJbLS1yTF07KSByLnBvcCgpOw0KDQogICAgaWYgKGNhcnJ5KSArK2U7DQogICAgZWxzZSByLnNoaWZ0KCk7DQoNCiAgICB5LmQgPSByOw0KICAgIHkuZSA9IGdldEJhc2UxMEV4cG9uZW50KHIsIGUpOw0KDQogICAgcmV0dXJuIGV4dGVybmFsID8gZmluYWxpc2UoeSwgQ3Rvci5wcmVjaXNpb24sIEN0b3Iucm91bmRpbmcpIDogeTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpbiBiYXNlIDIsIHJvdW5kIHRvIGBzZGAgc2lnbmlmaWNhbnQNCiAgICogZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJtYC4NCiAgICoNCiAgICogSWYgdGhlIG9wdGlvbmFsIGBzZGAgYXJndW1lbnQgaXMgcHJlc2VudCB0aGVuIHJldHVybiBiaW5hcnkgZXhwb25lbnRpYWwgbm90YXRpb24uDQogICAqDQogICAqIFtzZF0ge251bWJlcn0gU2lnbmlmaWNhbnQgZGlnaXRzLiBJbnRlZ2VyLCAxIHRvIE1BWF9ESUdJVFMgaW5jbHVzaXZlLg0KICAgKiBbcm1dIHtudW1iZXJ9IFJvdW5kaW5nIG1vZGUuIEludGVnZXIsIDAgdG8gOCBpbmNsdXNpdmUuDQogICAqDQogICAqLw0KICBQLnRvQmluYXJ5ID0gZnVuY3Rpb24gKHNkLCBybSkgew0KICAgIHJldHVybiB0b1N0cmluZ0JpbmFyeSh0aGlzLCAyLCBzZCwgcm0pOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCByb3VuZGVkIHRvIGEgbWF4aW11bSBvZiBgZHBgDQogICAqIGRlY2ltYWwgcGxhY2VzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJtYCBvciBgcm91bmRpbmdgIGlmIGBybWAgaXMgb21pdHRlZC4NCiAgICoNCiAgICogSWYgYGRwYCBpcyBvbWl0dGVkLCByZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBbZHBdIHtudW1iZXJ9IERlY2ltYWwgcGxhY2VzLiBJbnRlZ2VyLCAwIHRvIE1BWF9ESUdJVFMgaW5jbHVzaXZlLg0KICAgKiBbcm1dIHtudW1iZXJ9IFJvdW5kaW5nIG1vZGUuIEludGVnZXIsIDAgdG8gOCBpbmNsdXNpdmUuDQogICAqDQogICAqLw0KICBQLnRvRGVjaW1hbFBsYWNlcyA9IFAudG9EUCA9IGZ1bmN0aW9uIChkcCwgcm0pIHsNCiAgICB2YXIgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIHggPSBuZXcgQ3Rvcih4KTsNCiAgICBpZiAoZHAgPT09IHZvaWQgMCkgcmV0dXJuIHg7DQoNCiAgICBjaGVja0ludDMyKGRwLCAwLCBNQVhfRElHSVRTKTsNCg0KICAgIGlmIChybSA9PT0gdm9pZCAwKSBybSA9IEN0b3Iucm91bmRpbmc7DQogICAgZWxzZSBjaGVja0ludDMyKHJtLCAwLCA4KTsNCg0KICAgIHJldHVybiBmaW5hbGlzZSh4LCBkcCArIHguZSArIDEsIHJtKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpbiBleHBvbmVudGlhbCBub3RhdGlvbiByb3VuZGVkIHRvDQogICAqIGBkcGAgZml4ZWQgZGVjaW1hbCBwbGFjZXMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiBbZHBdIHtudW1iZXJ9IERlY2ltYWwgcGxhY2VzLiBJbnRlZ2VyLCAwIHRvIE1BWF9ESUdJVFMgaW5jbHVzaXZlLg0KICAgKiBbcm1dIHtudW1iZXJ9IFJvdW5kaW5nIG1vZGUuIEludGVnZXIsIDAgdG8gOCBpbmNsdXNpdmUuDQogICAqDQogICAqLw0KICBQLnRvRXhwb25lbnRpYWwgPSBmdW5jdGlvbiAoZHAsIHJtKSB7DQogICAgdmFyIHN0ciwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICBpZiAoZHAgPT09IHZvaWQgMCkgew0KICAgICAgc3RyID0gZmluaXRlVG9TdHJpbmcoeCwgdHJ1ZSk7DQogICAgfSBlbHNlIHsNCiAgICAgIGNoZWNrSW50MzIoZHAsIDAsIE1BWF9ESUdJVFMpOw0KDQogICAgICBpZiAocm0gPT09IHZvaWQgMCkgcm0gPSBDdG9yLnJvdW5kaW5nOw0KICAgICAgZWxzZSBjaGVja0ludDMyKHJtLCAwLCA4KTsNCg0KICAgICAgeCA9IGZpbmFsaXNlKG5ldyBDdG9yKHgpLCBkcCArIDEsIHJtKTsNCiAgICAgIHN0ciA9IGZpbml0ZVRvU3RyaW5nKHgsIHRydWUsIGRwICsgMSk7DQogICAgfQ0KDQogICAgcmV0dXJuIHguaXNOZWcoKSAmJiAheC5pc1plcm8oKSA/ICctJyArIHN0ciA6IHN0cjsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpbiBub3JtYWwgKGZpeGVkLXBvaW50KSBub3RhdGlvbiB0bw0KICAgKiBgZHBgIGZpeGVkIGRlY2ltYWwgcGxhY2VzIGFuZCByb3VuZGVkIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJtYCBvciBgcm91bmRpbmdgIGlmIGBybWAgaXMNCiAgICogb21pdHRlZC4NCiAgICoNCiAgICogQXMgd2l0aCBKYXZhU2NyaXB0IG51bWJlcnMsICgtMCkudG9GaXhlZCgwKSBpcyAnMCcsIGJ1dCBlLmcuICgtMC4wMDAwMSkudG9GaXhlZCgwKSBpcyAnLTAnLg0KICAgKg0KICAgKiBbZHBdIHtudW1iZXJ9IERlY2ltYWwgcGxhY2VzLiBJbnRlZ2VyLCAwIHRvIE1BWF9ESUdJVFMgaW5jbHVzaXZlLg0KICAgKiBbcm1dIHtudW1iZXJ9IFJvdW5kaW5nIG1vZGUuIEludGVnZXIsIDAgdG8gOCBpbmNsdXNpdmUuDQogICAqDQogICAqICgtMCkudG9GaXhlZCgwKSBpcyAnMCcsIGJ1dCAoLTAuMSkudG9GaXhlZCgwKSBpcyAnLTAnLg0KICAgKiAoLTApLnRvRml4ZWQoMSkgaXMgJzAuMCcsIGJ1dCAoLTAuMDEpLnRvRml4ZWQoMSkgaXMgJy0wLjAnLg0KICAgKiAoLTApLnRvRml4ZWQoMykgaXMgJzAuMDAwJy4NCiAgICogKC0wLjUpLnRvRml4ZWQoMCkgaXMgJy0wJy4NCiAgICoNCiAgICovDQogIFAudG9GaXhlZCA9IGZ1bmN0aW9uIChkcCwgcm0pIHsNCiAgICB2YXIgc3RyLCB5LA0KICAgICAgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmIChkcCA9PT0gdm9pZCAwKSB7DQogICAgICBzdHIgPSBmaW5pdGVUb1N0cmluZyh4KTsNCiAgICB9IGVsc2Ugew0KICAgICAgY2hlY2tJbnQzMihkcCwgMCwgTUFYX0RJR0lUUyk7DQoNCiAgICAgIGlmIChybSA9PT0gdm9pZCAwKSBybSA9IEN0b3Iucm91bmRpbmc7DQogICAgICBlbHNlIGNoZWNrSW50MzIocm0sIDAsIDgpOw0KDQogICAgICB5ID0gZmluYWxpc2UobmV3IEN0b3IoeCksIGRwICsgeC5lICsgMSwgcm0pOw0KICAgICAgc3RyID0gZmluaXRlVG9TdHJpbmcoeSwgZmFsc2UsIGRwICsgeS5lICsgMSk7DQogICAgfQ0KDQogICAgLy8gVG8gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gYWRkIHRoZSBtaW51cyBzaWduIGxvb2sgYXQgdGhlIHZhbHVlIGJlZm9yZSBpdCB3YXMgcm91bmRlZCwNCiAgICAvLyBpLmUuIGxvb2sgYXQgYHhgIHJhdGhlciB0aGFuIGB5YC4NCiAgICByZXR1cm4geC5pc05lZygpICYmICF4LmlzWmVybygpID8gJy0nICsgc3RyIDogc3RyOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGFuIGFycmF5IHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIGFzIGEgc2ltcGxlIGZyYWN0aW9uIHdpdGggYW4gaW50ZWdlcg0KICAgKiBudW1lcmF0b3IgYW5kIGFuIGludGVnZXIgZGVub21pbmF0b3IuDQogICAqDQogICAqIFRoZSBkZW5vbWluYXRvciB3aWxsIGJlIGEgcG9zaXRpdmUgbm9uLXplcm8gdmFsdWUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgbWF4aW11bQ0KICAgKiBkZW5vbWluYXRvci4gSWYgYSBtYXhpbXVtIGRlbm9taW5hdG9yIGlzIG5vdCBzcGVjaWZpZWQsIHRoZSBkZW5vbWluYXRvciB3aWxsIGJlIHRoZSBsb3dlc3QNCiAgICogdmFsdWUgbmVjZXNzYXJ5IHRvIHJlcHJlc2VudCB0aGUgbnVtYmVyIGV4YWN0bHkuDQogICAqDQogICAqIFttYXhEXSB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gTWF4aW11bSBkZW5vbWluYXRvci4gSW50ZWdlciA+PSAxIGFuZCA8IEluZmluaXR5Lg0KICAgKg0KICAgKi8NCiAgUC50b0ZyYWN0aW9uID0gZnVuY3Rpb24gKG1heEQpIHsNCiAgICB2YXIgZCwgZDAsIGQxLCBkMiwgZSwgaywgbiwgbjAsIG4xLCBwciwgcSwgciwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgeGQgPSB4LmQsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmICgheGQpIHJldHVybiBuZXcgQ3Rvcih4KTsNCg0KICAgIG4xID0gZDAgPSBuZXcgQ3RvcigxKTsNCiAgICBkMSA9IG4wID0gbmV3IEN0b3IoMCk7DQoNCiAgICBkID0gbmV3IEN0b3IoZDEpOw0KICAgIGUgPSBkLmUgPSBnZXRQcmVjaXNpb24oeGQpIC0geC5lIC0gMTsNCiAgICBrID0gZSAlIExPR19CQVNFOw0KICAgIGQuZFswXSA9IG1hdGhwb3coMTAsIGsgPCAwID8gTE9HX0JBU0UgKyBrIDogayk7DQoNCiAgICBpZiAobWF4RCA9PSBudWxsKSB7DQoNCiAgICAgIC8vIGQgaXMgMTAqKmUsIHRoZSBtaW5pbXVtIG1heC1kZW5vbWluYXRvciBuZWVkZWQuDQogICAgICBtYXhEID0gZSA+IDAgPyBkIDogbjE7DQogICAgfSBlbHNlIHsNCiAgICAgIG4gPSBuZXcgQ3RvcihtYXhEKTsNCiAgICAgIGlmICghbi5pc0ludCgpIHx8IG4ubHQobjEpKSB0aHJvdyBFcnJvcihpbnZhbGlkQXJndW1lbnQgKyBuKTsNCiAgICAgIG1heEQgPSBuLmd0KGQpID8gKGUgPiAwID8gZCA6IG4xKSA6IG47DQogICAgfQ0KDQogICAgZXh0ZXJuYWwgPSBmYWxzZTsNCiAgICBuID0gbmV3IEN0b3IoZGlnaXRzVG9TdHJpbmcoeGQpKTsNCiAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KICAgIEN0b3IucHJlY2lzaW9uID0gZSA9IHhkLmxlbmd0aCAqIExPR19CQVNFICogMjsNCg0KICAgIGZvciAoOzspICB7DQogICAgICBxID0gZGl2aWRlKG4sIGQsIDAsIDEsIDEpOw0KICAgICAgZDIgPSBkMC5wbHVzKHEudGltZXMoZDEpKTsNCiAgICAgIGlmIChkMi5jbXAobWF4RCkgPT0gMSkgYnJlYWs7DQogICAgICBkMCA9IGQxOw0KICAgICAgZDEgPSBkMjsNCiAgICAgIGQyID0gbjE7DQogICAgICBuMSA9IG4wLnBsdXMocS50aW1lcyhkMikpOw0KICAgICAgbjAgPSBkMjsNCiAgICAgIGQyID0gZDsNCiAgICAgIGQgPSBuLm1pbnVzKHEudGltZXMoZDIpKTsNCiAgICAgIG4gPSBkMjsNCiAgICB9DQoNCiAgICBkMiA9IGRpdmlkZShtYXhELm1pbnVzKGQwKSwgZDEsIDAsIDEsIDEpOw0KICAgIG4wID0gbjAucGx1cyhkMi50aW1lcyhuMSkpOw0KICAgIGQwID0gZDAucGx1cyhkMi50aW1lcyhkMSkpOw0KICAgIG4wLnMgPSBuMS5zID0geC5zOw0KDQogICAgLy8gRGV0ZXJtaW5lIHdoaWNoIGZyYWN0aW9uIGlzIGNsb3NlciB0byB4LCBuMC9kMCBvciBuMS9kMT8NCiAgICByID0gZGl2aWRlKG4xLCBkMSwgZSwgMSkubWludXMoeCkuYWJzKCkuY21wKGRpdmlkZShuMCwgZDAsIGUsIDEpLm1pbnVzKHgpLmFicygpKSA8IDENCiAgICAgICAgPyBbbjEsIGQxXSA6IFtuMCwgZDBdOw0KDQogICAgQ3Rvci5wcmVjaXNpb24gPSBwcjsNCiAgICBleHRlcm5hbCA9IHRydWU7DQoNCiAgICByZXR1cm4gcjsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoaXMgRGVjaW1hbCBpbiBiYXNlIDE2LCByb3VuZCB0byBgc2RgIHNpZ25pZmljYW50DQogICAqIGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGBybWAuDQogICAqDQogICAqIElmIHRoZSBvcHRpb25hbCBgc2RgIGFyZ3VtZW50IGlzIHByZXNlbnQgdGhlbiByZXR1cm4gYmluYXJ5IGV4cG9uZW50aWFsIG5vdGF0aW9uLg0KICAgKg0KICAgKiBbc2RdIHtudW1iZXJ9IFNpZ25pZmljYW50IGRpZ2l0cy4gSW50ZWdlciwgMSB0byBNQVhfRElHSVRTIGluY2x1c2l2ZS4NCiAgICogW3JtXSB7bnVtYmVyfSBSb3VuZGluZyBtb2RlLiBJbnRlZ2VyLCAwIHRvIDggaW5jbHVzaXZlLg0KICAgKg0KICAgKi8NCiAgUC50b0hleGFkZWNpbWFsID0gUC50b0hleCA9IGZ1bmN0aW9uIChzZCwgcm0pIHsNCiAgICByZXR1cm4gdG9TdHJpbmdCaW5hcnkodGhpcywgMTYsIHNkLCBybSk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm5zIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG5lYXJlc3QgbXVsdGlwbGUgb2YgYHlgIGluIHRoZSBkaXJlY3Rpb24gb2Ygcm91bmRpbmcNCiAgICogbW9kZSBgcm1gLCBvciBgRGVjaW1hbC5yb3VuZGluZ2AgaWYgYHJtYCBpcyBvbWl0dGVkLCB0byB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBUaGUgcmV0dXJuIHZhbHVlIHdpbGwgYWx3YXlzIGhhdmUgdGhlIHNhbWUgc2lnbiBhcyB0aGlzIERlY2ltYWwsIHVubGVzcyBlaXRoZXIgdGhpcyBEZWNpbWFsDQogICAqIG9yIGB5YCBpcyBOYU4sIGluIHdoaWNoIGNhc2UgdGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIGFsc28gYmUgTmFOLg0KICAgKg0KICAgKiBUaGUgcmV0dXJuIHZhbHVlIGlzIG5vdCBhZmZlY3RlZCBieSB0aGUgdmFsdWUgb2YgYHByZWNpc2lvbmAuDQogICAqDQogICAqIHkge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9IFRoZSBtYWduaXR1ZGUgdG8gcm91bmQgdG8gYSBtdWx0aXBsZSBvZi4NCiAgICogW3JtXSB7bnVtYmVyfSBSb3VuZGluZyBtb2RlLiBJbnRlZ2VyLCAwIHRvIDggaW5jbHVzaXZlLg0KICAgKg0KICAgKiAndG9OZWFyZXN0KCkgcm91bmRpbmcgbW9kZSBub3QgYW4gaW50ZWdlcjoge3JtfScNCiAgICogJ3RvTmVhcmVzdCgpIHJvdW5kaW5nIG1vZGUgb3V0IG9mIHJhbmdlOiB7cm19Jw0KICAgKg0KICAgKi8NCiAgUC50b05lYXJlc3QgPSBmdW5jdGlvbiAoeSwgcm0pIHsNCiAgICB2YXIgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIHggPSBuZXcgQ3Rvcih4KTsNCg0KICAgIGlmICh5ID09IG51bGwpIHsNCg0KICAgICAgLy8gSWYgeCBpcyBub3QgZmluaXRlLCByZXR1cm4geC4NCiAgICAgIGlmICgheC5kKSByZXR1cm4geDsNCg0KICAgICAgeSA9IG5ldyBDdG9yKDEpOw0KICAgICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KICAgIH0gZWxzZSB7DQogICAgICB5ID0gbmV3IEN0b3IoeSk7DQogICAgICBpZiAocm0gPT09IHZvaWQgMCkgew0KICAgICAgICBybSA9IEN0b3Iucm91bmRpbmc7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBjaGVja0ludDMyKHJtLCAwLCA4KTsNCiAgICAgIH0NCg0KICAgICAgLy8gSWYgeCBpcyBub3QgZmluaXRlLCByZXR1cm4geCBpZiB5IGlzIG5vdCBOYU4sIGVsc2UgTmFOLg0KICAgICAgaWYgKCF4LmQpIHJldHVybiB5LnMgPyB4IDogeTsNCg0KICAgICAgLy8gSWYgeSBpcyBub3QgZmluaXRlLCByZXR1cm4gSW5maW5pdHkgd2l0aCB0aGUgc2lnbiBvZiB4IGlmIHkgaXMgSW5maW5pdHksIGVsc2UgTmFOLg0KICAgICAgaWYgKCF5LmQpIHsNCiAgICAgICAgaWYgKHkucykgeS5zID0geC5zOw0KICAgICAgICByZXR1cm4geTsNCiAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBJZiB5IGlzIG5vdCB6ZXJvLCBjYWxjdWxhdGUgdGhlIG5lYXJlc3QgbXVsdGlwbGUgb2YgeSB0byB4Lg0KICAgIGlmICh5LmRbMF0pIHsNCiAgICAgIGV4dGVybmFsID0gZmFsc2U7DQogICAgICB4ID0gZGl2aWRlKHgsIHksIDAsIHJtLCAxKS50aW1lcyh5KTsNCiAgICAgIGV4dGVybmFsID0gdHJ1ZTsNCiAgICAgIGZpbmFsaXNlKHgpOw0KDQogICAgLy8gSWYgeSBpcyB6ZXJvLCByZXR1cm4gemVybyB3aXRoIHRoZSBzaWduIG9mIHguDQogICAgfSBlbHNlIHsNCiAgICAgIHkucyA9IHguczsNCiAgICAgIHggPSB5Ow0KICAgIH0NCg0KICAgIHJldHVybiB4Ow0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgY29udmVydGVkIHRvIGEgbnVtYmVyIHByaW1pdGl2ZS4NCiAgICogWmVybyBrZWVwcyBpdHMgc2lnbi4NCiAgICoNCiAgICovDQogIFAudG9OdW1iZXIgPSBmdW5jdGlvbiAoKSB7DQogICAgcmV0dXJuICt0aGlzOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIGluIGJhc2UgOCwgcm91bmQgdG8gYHNkYCBzaWduaWZpY2FudA0KICAgKiBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm1gLg0KICAgKg0KICAgKiBJZiB0aGUgb3B0aW9uYWwgYHNkYCBhcmd1bWVudCBpcyBwcmVzZW50IHRoZW4gcmV0dXJuIGJpbmFyeSBleHBvbmVudGlhbCBub3RhdGlvbi4NCiAgICoNCiAgICogW3NkXSB7bnVtYmVyfSBTaWduaWZpY2FudCBkaWdpdHMuIEludGVnZXIsIDEgdG8gTUFYX0RJR0lUUyBpbmNsdXNpdmUuDQogICAqIFtybV0ge251bWJlcn0gUm91bmRpbmcgbW9kZS4gSW50ZWdlciwgMCB0byA4IGluY2x1c2l2ZS4NCiAgICoNCiAgICovDQogIFAudG9PY3RhbCA9IGZ1bmN0aW9uIChzZCwgcm0pIHsNCiAgICByZXR1cm4gdG9TdHJpbmdCaW5hcnkodGhpcywgOCwgc2QsIHJtKTsNCiAgfTsNCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgcmFpc2VkIHRvIHRoZSBwb3dlciBgeWAsIHJvdW5kZWQNCiAgICogdG8gYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogRUNNQVNjcmlwdCBjb21wbGlhbnQuDQogICAqDQogICAqICAgcG93KHgsIE5hTikgICAgICAgICAgICAgICAgICAgICAgICAgICA9IE5hTg0KICAgKiAgIHBvdyh4LCDCsTApICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMQ0KDQogICAqICAgcG93KE5hTiwgbm9uLXplcm8pICAgICAgICAgICAgICAgICAgICA9IE5hTg0KICAgKiAgIHBvdyhhYnMoeCkgPiAxLCArSW5maW5pdHkpICAgICAgICAgICAgPSArSW5maW5pdHkNCiAgICogICBwb3coYWJzKHgpID4gMSwgLUluZmluaXR5KSAgICAgICAgICAgID0gKzANCiAgICogICBwb3coYWJzKHgpID09IDEsIMKxSW5maW5pdHkpICAgICAgICAgICA9IE5hTg0KICAgKiAgIHBvdyhhYnMoeCkgPCAxLCArSW5maW5pdHkpICAgICAgICAgICAgPSArMA0KICAgKiAgIHBvdyhhYnMoeCkgPCAxLCAtSW5maW5pdHkpICAgICAgICAgICAgPSArSW5maW5pdHkNCiAgICogICBwb3coK0luZmluaXR5LCB5ID4gMCkgICAgICAgICAgICAgICAgID0gK0luZmluaXR5DQogICAqICAgcG93KCtJbmZpbml0eSwgeSA8IDApICAgICAgICAgICAgICAgICA9ICswDQogICAqICAgcG93KC1JbmZpbml0eSwgb2RkIGludGVnZXIgPiAwKSAgICAgICA9IC1JbmZpbml0eQ0KICAgKiAgIHBvdygtSW5maW5pdHksIGV2ZW4gaW50ZWdlciA+IDApICAgICAgPSArSW5maW5pdHkNCiAgICogICBwb3coLUluZmluaXR5LCBvZGQgaW50ZWdlciA8IDApICAgICAgID0gLTANCiAgICogICBwb3coLUluZmluaXR5LCBldmVuIGludGVnZXIgPCAwKSAgICAgID0gKzANCiAgICogICBwb3coKzAsIHkgPiAwKSAgICAgICAgICAgICAgICAgICAgICAgID0gKzANCiAgICogICBwb3coKzAsIHkgPCAwKSAgICAgICAgICAgICAgICAgICAgICAgID0gK0luZmluaXR5DQogICAqICAgcG93KC0wLCBvZGQgaW50ZWdlciA+IDApICAgICAgICAgICAgICA9IC0wDQogICAqICAgcG93KC0wLCBldmVuIGludGVnZXIgPiAwKSAgICAgICAgICAgICA9ICswDQogICAqICAgcG93KC0wLCBvZGQgaW50ZWdlciA8IDApICAgICAgICAgICAgICA9IC1JbmZpbml0eQ0KICAgKiAgIHBvdygtMCwgZXZlbiBpbnRlZ2VyIDwgMCkgICAgICAgICAgICAgPSArSW5maW5pdHkNCiAgICogICBwb3coZmluaXRlIHggPCAwLCBmaW5pdGUgbm9uLWludGVnZXIpID0gTmFODQogICAqDQogICAqIEZvciBub24taW50ZWdlciBvciB2ZXJ5IGxhcmdlIGV4cG9uZW50cyBwb3coeCwgeSkgaXMgY2FsY3VsYXRlZCB1c2luZw0KICAgKg0KICAgKiAgIHheeSA9IGV4cCh5KmxuKHgpKQ0KICAgKg0KICAgKiBBc3N1bWluZyB0aGUgZmlyc3QgMTUgcm91bmRpbmcgZGlnaXRzIGFyZSBlYWNoIGVxdWFsbHkgbGlrZWx5IHRvIGJlIGFueSBkaWdpdCAwLTksIHRoZQ0KICAgKiBwcm9iYWJpbGl0eSBvZiBhbiBpbmNvcnJlY3RseSByb3VuZGVkIHJlc3VsdA0KICAgKiBQKFs0OV05ezE0fSB8IFs1MF0wezE0fSkgPSAyICogMC4yICogMTBeLTE0ID0gNGUtMTUgPSAxLzIuNWUrMTQNCiAgICogaS5lLiAxIGluIDI1MCwwMDAsMDAwLDAwMCwwMDANCiAgICoNCiAgICogSWYgYSByZXN1bHQgaXMgaW5jb3JyZWN0bHkgcm91bmRlZCB0aGUgbWF4aW11bSBlcnJvciB3aWxsIGJlIDEgdWxwICh1bml0IGluIGxhc3QgcGxhY2UpLg0KICAgKg0KICAgKiB5IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBUaGUgcG93ZXIgdG8gd2hpY2ggdG8gcmFpc2UgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKi8NCiAgUC50b1Bvd2VyID0gUC5wb3cgPSBmdW5jdGlvbiAoeSkgew0KICAgIHZhciBlLCBrLCBwciwgciwgcm0sIHMsDQogICAgICB4ID0gdGhpcywNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yLA0KICAgICAgeW4gPSArKHkgPSBuZXcgQ3Rvcih5KSk7DQoNCiAgICAvLyBFaXRoZXIgwrFJbmZpbml0eSwgTmFOIG9yIMKxMD8NCiAgICBpZiAoIXguZCB8fCAheS5kIHx8ICF4LmRbMF0gfHwgIXkuZFswXSkgcmV0dXJuIG5ldyBDdG9yKG1hdGhwb3coK3gsIHluKSk7DQoNCiAgICB4ID0gbmV3IEN0b3IoeCk7DQoNCiAgICBpZiAoeC5lcSgxKSkgcmV0dXJuIHg7DQoNCiAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KICAgIHJtID0gQ3Rvci5yb3VuZGluZzsNCg0KICAgIGlmICh5LmVxKDEpKSByZXR1cm4gZmluYWxpc2UoeCwgcHIsIHJtKTsNCg0KICAgIC8vIHkgZXhwb25lbnQNCiAgICBlID0gbWF0aGZsb29yKHkuZSAvIExPR19CQVNFKTsNCg0KICAgIC8vIElmIHkgaXMgYSBzbWFsbCBpbnRlZ2VyIHVzZSB0aGUgJ2V4cG9uZW50aWF0aW9uIGJ5IHNxdWFyaW5nJyBhbGdvcml0aG0uDQogICAgaWYgKGUgPj0geS5kLmxlbmd0aCAtIDEgJiYgKGsgPSB5biA8IDAgPyAteW4gOiB5bikgPD0gTUFYX1NBRkVfSU5URUdFUikgew0KICAgICAgciA9IGludFBvdyhDdG9yLCB4LCBrLCBwcik7DQogICAgICByZXR1cm4geS5zIDwgMCA/IG5ldyBDdG9yKDEpLmRpdihyKSA6IGZpbmFsaXNlKHIsIHByLCBybSk7DQogICAgfQ0KDQogICAgcyA9IHguczsNCg0KICAgIC8vIGlmIHggaXMgbmVnYXRpdmUNCiAgICBpZiAocyA8IDApIHsNCg0KICAgICAgLy8gaWYgeSBpcyBub3QgYW4gaW50ZWdlcg0KICAgICAgaWYgKGUgPCB5LmQubGVuZ3RoIC0gMSkgcmV0dXJuIG5ldyBDdG9yKE5hTik7DQoNCiAgICAgIC8vIFJlc3VsdCBpcyBwb3NpdGl2ZSBpZiB4IGlzIG5lZ2F0aXZlIGFuZCB0aGUgbGFzdCBkaWdpdCBvZiBpbnRlZ2VyIHkgaXMgZXZlbi4NCiAgICAgIGlmICgoeS5kW2VdICYgMSkgPT0gMCkgcyA9IDE7DQoNCiAgICAgIC8vIGlmIHguZXEoLTEpDQogICAgICBpZiAoeC5lID09IDAgJiYgeC5kWzBdID09IDEgJiYgeC5kLmxlbmd0aCA9PSAxKSB7DQogICAgICAgIHgucyA9IHM7DQogICAgICAgIHJldHVybiB4Ow0KICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIEVzdGltYXRlIHJlc3VsdCBleHBvbmVudC4NCiAgICAvLyB4XnkgPSAxMF5lLCAgd2hlcmUgZSA9IHkgKiBsb2cxMCh4KQ0KICAgIC8vIGxvZzEwKHgpID0gbG9nMTAoeF9zaWduaWZpY2FuZCkgKyB4X2V4cG9uZW50DQogICAgLy8gbG9nMTAoeF9zaWduaWZpY2FuZCkgPSBsbih4X3NpZ25pZmljYW5kKSAvIGxuKDEwKQ0KICAgIGsgPSBtYXRocG93KCt4LCB5bik7DQogICAgZSA9IGsgPT0gMCB8fCAhaXNGaW5pdGUoaykNCiAgICAgID8gbWF0aGZsb29yKHluICogKE1hdGgubG9nKCcwLicgKyBkaWdpdHNUb1N0cmluZyh4LmQpKSAvIE1hdGguTE4xMCArIHguZSArIDEpKQ0KICAgICAgOiBuZXcgQ3RvcihrICsgJycpLmU7DQoNCiAgICAvLyBFeHBvbmVudCBlc3RpbWF0ZSBtYXkgYmUgaW5jb3JyZWN0IGUuZy4geDogMC45OTk5OTk5OTk5OTk5OTk5OTksIHk6IDIuMjksIGU6IDAsIHIuZTogLTEuDQoNCiAgICAvLyBPdmVyZmxvdy91bmRlcmZsb3c/DQogICAgaWYgKGUgPiBDdG9yLm1heEUgKyAxIHx8IGUgPCBDdG9yLm1pbkUgLSAxKSByZXR1cm4gbmV3IEN0b3IoZSA+IDAgPyBzIC8gMCA6IDApOw0KDQogICAgZXh0ZXJuYWwgPSBmYWxzZTsNCiAgICBDdG9yLnJvdW5kaW5nID0geC5zID0gMTsNCg0KICAgIC8vIEVzdGltYXRlIHRoZSBleHRyYSBndWFyZCBkaWdpdHMgbmVlZGVkIHRvIGVuc3VyZSBmaXZlIGNvcnJlY3Qgcm91bmRpbmcgZGlnaXRzIGZyb20NCiAgICAvLyBuYXR1cmFsTG9nYXJpdGhtKHgpLiBFeGFtcGxlIG9mIGZhaWx1cmUgd2l0aG91dCB0aGVzZSBleHRyYSBkaWdpdHMgKHByZWNpc2lvbjogMTApOg0KICAgIC8vIG5ldyBEZWNpbWFsKDIuMzI0NTYpLnBvdygnMjA4Nzk4NzQzNjUzNDU2Ni40NjQxMScpDQogICAgLy8gc2hvdWxkIGJlIDEuMTYyMzc3ODIzZSs3NjQ5MTQ5MDUxNzM4MTUsIGJ1dCBpcyAxLjE2MjM1NTgyM2UrNzY0OTE0OTA1MTczODE1DQogICAgayA9IE1hdGgubWluKDEyLCAoZSArICcnKS5sZW5ndGgpOw0KDQogICAgLy8gciA9IHheeSA9IGV4cCh5KmxuKHgpKQ0KICAgIHIgPSBuYXR1cmFsRXhwb25lbnRpYWwoeS50aW1lcyhuYXR1cmFsTG9nYXJpdGhtKHgsIHByICsgaykpLCBwcik7DQoNCiAgICAvLyByIG1heSBiZSBJbmZpbml0eSwgZS5nLiAoMC45OTk5OTk5OTk5OTk5OTk5KS5wb3coLTFlKzQwKQ0KICAgIGlmIChyLmQpIHsNCg0KICAgICAgLy8gVHJ1bmNhdGUgdG8gdGhlIHJlcXVpcmVkIHByZWNpc2lvbiBwbHVzIGZpdmUgcm91bmRpbmcgZGlnaXRzLg0KICAgICAgciA9IGZpbmFsaXNlKHIsIHByICsgNSwgMSk7DQoNCiAgICAgIC8vIElmIHRoZSByb3VuZGluZyBkaWdpdHMgYXJlIFs0OV05OTk5IG9yIFs1MF0wMDAwIGluY3JlYXNlIHRoZSBwcmVjaXNpb24gYnkgMTAgYW5kIHJlY2FsY3VsYXRlDQogICAgICAvLyB0aGUgcmVzdWx0Lg0KICAgICAgaWYgKGNoZWNrUm91bmRpbmdEaWdpdHMoci5kLCBwciwgcm0pKSB7DQogICAgICAgIGUgPSBwciArIDEwOw0KDQogICAgICAgIC8vIFRydW5jYXRlIHRvIHRoZSBpbmNyZWFzZWQgcHJlY2lzaW9uIHBsdXMgZml2ZSByb3VuZGluZyBkaWdpdHMuDQogICAgICAgIHIgPSBmaW5hbGlzZShuYXR1cmFsRXhwb25lbnRpYWwoeS50aW1lcyhuYXR1cmFsTG9nYXJpdGhtKHgsIGUgKyBrKSksIGUpLCBlICsgNSwgMSk7DQoNCiAgICAgICAgLy8gQ2hlY2sgZm9yIDE0IG5pbmVzIGZyb20gdGhlIDJuZCByb3VuZGluZyBkaWdpdCAodGhlIGZpcnN0IHJvdW5kaW5nIGRpZ2l0IG1heSBiZSA0IG9yIDkpLg0KICAgICAgICBpZiAoK2RpZ2l0c1RvU3RyaW5nKHIuZCkuc2xpY2UocHIgKyAxLCBwciArIDE1KSArIDEgPT0gMWUxNCkgew0KICAgICAgICAgIHIgPSBmaW5hbGlzZShyLCBwciArIDEsIDApOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KDQogICAgci5zID0gczsNCiAgICBleHRlcm5hbCA9IHRydWU7DQogICAgQ3Rvci5yb3VuZGluZyA9IHJtOw0KDQogICAgcmV0dXJuIGZpbmFsaXNlKHIsIHByLCBybSk7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGlzIERlY2ltYWwgcm91bmRlZCB0byBgc2RgIHNpZ25pZmljYW50IGRpZ2l0cw0KICAgKiB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqIFJldHVybiBleHBvbmVudGlhbCBub3RhdGlvbiBpZiBgc2RgIGlzIGxlc3MgdGhhbiB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBuZWNlc3NhcnkgdG8gcmVwcmVzZW50DQogICAqIHRoZSBpbnRlZ2VyIHBhcnQgb2YgdGhlIHZhbHVlIGluIG5vcm1hbCBub3RhdGlvbi4NCiAgICoNCiAgICogW3NkXSB7bnVtYmVyfSBTaWduaWZpY2FudCBkaWdpdHMuIEludGVnZXIsIDEgdG8gTUFYX0RJR0lUUyBpbmNsdXNpdmUuDQogICAqIFtybV0ge251bWJlcn0gUm91bmRpbmcgbW9kZS4gSW50ZWdlciwgMCB0byA4IGluY2x1c2l2ZS4NCiAgICoNCiAgICovDQogIFAudG9QcmVjaXNpb24gPSBmdW5jdGlvbiAoc2QsIHJtKSB7DQogICAgdmFyIHN0ciwNCiAgICAgIHggPSB0aGlzLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3I7DQoNCiAgICBpZiAoc2QgPT09IHZvaWQgMCkgew0KICAgICAgc3RyID0gZmluaXRlVG9TdHJpbmcoeCwgeC5lIDw9IEN0b3IudG9FeHBOZWcgfHwgeC5lID49IEN0b3IudG9FeHBQb3MpOw0KICAgIH0gZWxzZSB7DQogICAgICBjaGVja0ludDMyKHNkLCAxLCBNQVhfRElHSVRTKTsNCg0KICAgICAgaWYgKHJtID09PSB2b2lkIDApIHJtID0gQ3Rvci5yb3VuZGluZzsNCiAgICAgIGVsc2UgY2hlY2tJbnQzMihybSwgMCwgOCk7DQoNCiAgICAgIHggPSBmaW5hbGlzZShuZXcgQ3Rvcih4KSwgc2QsIHJtKTsNCiAgICAgIHN0ciA9IGZpbml0ZVRvU3RyaW5nKHgsIHNkIDw9IHguZSB8fCB4LmUgPD0gQ3Rvci50b0V4cE5lZywgc2QpOw0KICAgIH0NCg0KICAgIHJldHVybiB4LmlzTmVnKCkgJiYgIXguaXNaZXJvKCkgPyAnLScgKyBzdHIgOiBzdHI7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIHJvdW5kZWQgdG8gYSBtYXhpbXVtIG9mIGBzZGANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJtYCwgb3IgdG8gYHByZWNpc2lvbmAgYW5kIGByb3VuZGluZ2AgcmVzcGVjdGl2ZWx5IGlmDQogICAqIG9taXR0ZWQuDQogICAqDQogICAqIFtzZF0ge251bWJlcn0gU2lnbmlmaWNhbnQgZGlnaXRzLiBJbnRlZ2VyLCAxIHRvIE1BWF9ESUdJVFMgaW5jbHVzaXZlLg0KICAgKiBbcm1dIHtudW1iZXJ9IFJvdW5kaW5nIG1vZGUuIEludGVnZXIsIDAgdG8gOCBpbmNsdXNpdmUuDQogICAqDQogICAqICd0b1NEKCkgZGlnaXRzIG91dCBvZiByYW5nZToge3NkfScNCiAgICogJ3RvU0QoKSBkaWdpdHMgbm90IGFuIGludGVnZXI6IHtzZH0nDQogICAqICd0b1NEKCkgcm91bmRpbmcgbW9kZSBub3QgYW4gaW50ZWdlcjoge3JtfScNCiAgICogJ3RvU0QoKSByb3VuZGluZyBtb2RlIG91dCBvZiByYW5nZToge3JtfScNCiAgICoNCiAgICovDQogIFAudG9TaWduaWZpY2FudERpZ2l0cyA9IFAudG9TRCA9IGZ1bmN0aW9uIChzZCwgcm0pIHsNCiAgICB2YXIgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmIChzZCA9PT0gdm9pZCAwKSB7DQogICAgICBzZCA9IEN0b3IucHJlY2lzaW9uOw0KICAgICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KICAgIH0gZWxzZSB7DQogICAgICBjaGVja0ludDMyKHNkLCAxLCBNQVhfRElHSVRTKTsNCg0KICAgICAgaWYgKHJtID09PSB2b2lkIDApIHJtID0gQ3Rvci5yb3VuZGluZzsNCiAgICAgIGVsc2UgY2hlY2tJbnQzMihybSwgMCwgOCk7DQogICAgfQ0KDQogICAgcmV0dXJuIGZpbmFsaXNlKG5ldyBDdG9yKHgpLCBzZCwgcm0pOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsLg0KICAgKg0KICAgKiBSZXR1cm4gZXhwb25lbnRpYWwgbm90YXRpb24gaWYgdGhpcyBEZWNpbWFsIGhhcyBhIHBvc2l0aXZlIGV4cG9uZW50IGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbg0KICAgKiBgdG9FeHBQb3NgLCBvciBhIG5lZ2F0aXZlIGV4cG9uZW50IGVxdWFsIHRvIG9yIGxlc3MgdGhhbiBgdG9FeHBOZWdgLg0KICAgKg0KICAgKi8NCiAgUC50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvciwNCiAgICAgIHN0ciA9IGZpbml0ZVRvU3RyaW5nKHgsIHguZSA8PSBDdG9yLnRvRXhwTmVnIHx8IHguZSA+PSBDdG9yLnRvRXhwUG9zKTsNCg0KICAgIHJldHVybiB4LmlzTmVnKCkgJiYgIXguaXNaZXJvKCkgPyAnLScgKyBzdHIgOiBzdHI7DQogIH07DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsIHRydW5jYXRlZCB0byBhIHdob2xlIG51bWJlci4NCiAgICoNCiAgICovDQogIFAudHJ1bmNhdGVkID0gUC50cnVuYyA9IGZ1bmN0aW9uICgpIHsNCiAgICByZXR1cm4gZmluYWxpc2UobmV3IHRoaXMuY29uc3RydWN0b3IodGhpcyksIHRoaXMuZSArIDEsIDEpOw0KICB9Ow0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhpcyBEZWNpbWFsLg0KICAgKiBVbmxpa2UgYHRvU3RyaW5nYCwgbmVnYXRpdmUgemVybyB3aWxsIGluY2x1ZGUgdGhlIG1pbnVzIHNpZ24uDQogICAqDQogICAqLw0KICBQLnZhbHVlT2YgPSBQLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgeCA9IHRoaXMsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvciwNCiAgICAgIHN0ciA9IGZpbml0ZVRvU3RyaW5nKHgsIHguZSA8PSBDdG9yLnRvRXhwTmVnIHx8IHguZSA+PSBDdG9yLnRvRXhwUG9zKTsNCg0KICAgIHJldHVybiB4LmlzTmVnKCkgPyAnLScgKyBzdHIgOiBzdHI7DQogIH07DQoNCg0KICAvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBEZWNpbWFsLnByb3RvdHlwZSAoUCkgYW5kL29yIERlY2ltYWwgbWV0aG9kcywgYW5kIHRoZWlyIGNhbGxlcnMuDQoNCg0KICAvKg0KICAgKiAgZGlnaXRzVG9TdHJpbmcgICAgICAgICAgIFAuY3ViZVJvb3QsIFAubG9nYXJpdGhtLCBQLnNxdWFyZVJvb3QsIFAudG9GcmFjdGlvbiwgUC50b1Bvd2VyLA0KICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbml0ZVRvU3RyaW5nLCBuYXR1cmFsRXhwb25lbnRpYWwsIG5hdHVyYWxMb2dhcml0aG0NCiAgICogIGNoZWNrSW50MzIgICAgICAgICAgICAgICBQLnRvRGVjaW1hbFBsYWNlcywgUC50b0V4cG9uZW50aWFsLCBQLnRvRml4ZWQsIFAudG9OZWFyZXN0LA0KICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIFAudG9QcmVjaXNpb24sIFAudG9TaWduaWZpY2FudERpZ2l0cywgdG9TdHJpbmdCaW5hcnksIHJhbmRvbQ0KICAgKiAgY2hlY2tSb3VuZGluZ0RpZ2l0cyAgICAgIFAubG9nYXJpdGhtLCBQLnRvUG93ZXIsIG5hdHVyYWxFeHBvbmVudGlhbCwgbmF0dXJhbExvZ2FyaXRobQ0KICAgKiAgY29udmVydEJhc2UgICAgICAgICAgICAgIHRvU3RyaW5nQmluYXJ5LCBwYXJzZU90aGVyDQogICAqICBjb3MgICAgICAgICAgICAgICAgICAgICAgUC5jb3MNCiAgICogIGRpdmlkZSAgICAgICAgICAgICAgICAgICBQLmF0YW5oLCBQLmN1YmVSb290LCBQLmRpdmlkZWRCeSwgUC5kaXZpZGVkVG9JbnRlZ2VyQnksDQogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUC5sb2dhcml0aG0sIFAubW9kdWxvLCBQLnNxdWFyZVJvb3QsIFAudGFuLCBQLnRhbmgsIFAudG9GcmFjdGlvbiwNCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBQLnRvTmVhcmVzdCwgdG9TdHJpbmdCaW5hcnksIG5hdHVyYWxFeHBvbmVudGlhbCwgbmF0dXJhbExvZ2FyaXRobSwNCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICB0YXlsb3JTZXJpZXMsIGF0YW4yLCBwYXJzZU90aGVyDQogICAqICBmaW5hbGlzZSAgICAgICAgICAgICAgICAgUC5hYnNvbHV0ZVZhbHVlLCBQLmF0YW4sIFAuYXRhbmgsIFAuY2VpbCwgUC5jb3MsIFAuY29zaCwNCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBQLmN1YmVSb290LCBQLmRpdmlkZWRUb0ludGVnZXJCeSwgUC5mbG9vciwgUC5sb2dhcml0aG0sIFAubWludXMsDQogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUC5tb2R1bG8sIFAubmVnYXRlZCwgUC5wbHVzLCBQLnJvdW5kLCBQLnNpbiwgUC5zaW5oLCBQLnNxdWFyZVJvb3QsDQogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUC50YW4sIFAudGltZXMsIFAudG9EZWNpbWFsUGxhY2VzLCBQLnRvRXhwb25lbnRpYWwsIFAudG9GaXhlZCwNCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBQLnRvTmVhcmVzdCwgUC50b1Bvd2VyLCBQLnRvUHJlY2lzaW9uLCBQLnRvU2lnbmlmaWNhbnREaWdpdHMsDQogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUC50cnVuY2F0ZWQsIGRpdmlkZSwgZ2V0TG4xMCwgZ2V0UGksIG5hdHVyYWxFeHBvbmVudGlhbCwNCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBuYXR1cmFsTG9nYXJpdGhtLCBjZWlsLCBmbG9vciwgcm91bmQsIHRydW5jDQogICAqICBmaW5pdGVUb1N0cmluZyAgICAgICAgICAgUC50b0V4cG9uZW50aWFsLCBQLnRvRml4ZWQsIFAudG9QcmVjaXNpb24sIFAudG9TdHJpbmcsIFAudmFsdWVPZiwNCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICB0b1N0cmluZ0JpbmFyeQ0KICAgKiAgZ2V0QmFzZTEwRXhwb25lbnQgICAgICAgIFAubWludXMsIFAucGx1cywgUC50aW1lcywgcGFyc2VPdGhlcg0KICAgKiAgZ2V0TG4xMCAgICAgICAgICAgICAgICAgIFAubG9nYXJpdGhtLCBuYXR1cmFsTG9nYXJpdGhtDQogICAqICBnZXRQaSAgICAgICAgICAgICAgICAgICAgUC5hY29zLCBQLmFzaW4sIFAuYXRhbiwgdG9MZXNzVGhhbkhhbGZQaSwgYXRhbjINCiAgICogIGdldFByZWNpc2lvbiAgICAgICAgICAgICBQLnByZWNpc2lvbiwgUC50b0ZyYWN0aW9uDQogICAqICBnZXRaZXJvU3RyaW5nICAgICAgICAgICAgZGlnaXRzVG9TdHJpbmcsIGZpbml0ZVRvU3RyaW5nDQogICAqICBpbnRQb3cgICAgICAgICAgICAgICAgICAgUC50b1Bvd2VyLCBwYXJzZU90aGVyDQogICAqICBpc09kZCAgICAgICAgICAgICAgICAgICAgdG9MZXNzVGhhbkhhbGZQaQ0KICAgKiAgbWF4T3JNaW4gICAgICAgICAgICAgICAgIG1heCwgbWluDQogICAqICBuYXR1cmFsRXhwb25lbnRpYWwgICAgICAgUC5uYXR1cmFsRXhwb25lbnRpYWwsIFAudG9Qb3dlcg0KICAgKiAgbmF0dXJhbExvZ2FyaXRobSAgICAgICAgIFAuYWNvc2gsIFAuYXNpbmgsIFAuYXRhbmgsIFAubG9nYXJpdGhtLCBQLm5hdHVyYWxMb2dhcml0aG0sDQogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgUC50b1Bvd2VyLCBuYXR1cmFsRXhwb25lbnRpYWwNCiAgICogIG5vbkZpbml0ZVRvU3RyaW5nICAgICAgICBmaW5pdGVUb1N0cmluZywgdG9TdHJpbmdCaW5hcnkNCiAgICogIHBhcnNlRGVjaW1hbCAgICAgICAgICAgICBEZWNpbWFsDQogICAqICBwYXJzZU90aGVyICAgICAgICAgICAgICAgRGVjaW1hbA0KICAgKiAgc2luICAgICAgICAgICAgICAgICAgICAgIFAuc2luDQogICAqICB0YXlsb3JTZXJpZXMgICAgICAgICAgICAgUC5jb3NoLCBQLnNpbmgsIGNvcywgc2luDQogICAqICB0b0xlc3NUaGFuSGFsZlBpICAgICAgICAgUC5jb3MsIFAuc2luDQogICAqICB0b1N0cmluZ0JpbmFyeSAgICAgICAgICAgUC50b0JpbmFyeSwgUC50b0hleGFkZWNpbWFsLCBQLnRvT2N0YWwNCiAgICogIHRydW5jYXRlICAgICAgICAgICAgICAgICBpbnRQb3cNCiAgICoNCiAgICogIFRocm93czogICAgICAgICAgICAgICAgICBQLmxvZ2FyaXRobSwgUC5wcmVjaXNpb24sIFAudG9GcmFjdGlvbiwgY2hlY2tJbnQzMiwgZ2V0TG4xMCwgZ2V0UGksDQogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0dXJhbExvZ2FyaXRobSwgY29uZmlnLCBwYXJzZU90aGVyLCByYW5kb20sIERlY2ltYWwNCiAgICovDQoNCg0KICBmdW5jdGlvbiBkaWdpdHNUb1N0cmluZyhkKSB7DQogICAgdmFyIGksIGssIHdzLA0KICAgICAgaW5kZXhPZkxhc3RXb3JkID0gZC5sZW5ndGggLSAxLA0KICAgICAgc3RyID0gJycsDQogICAgICB3ID0gZFswXTsNCg0KICAgIGlmIChpbmRleE9mTGFzdFdvcmQgPiAwKSB7DQogICAgICBzdHIgKz0gdzsNCiAgICAgIGZvciAoaSA9IDE7IGkgPCBpbmRleE9mTGFzdFdvcmQ7IGkrKykgew0KICAgICAgICB3cyA9IGRbaV0gKyAnJzsNCiAgICAgICAgayA9IExPR19CQVNFIC0gd3MubGVuZ3RoOw0KICAgICAgICBpZiAoaykgc3RyICs9IGdldFplcm9TdHJpbmcoayk7DQogICAgICAgIHN0ciArPSB3czsNCiAgICAgIH0NCg0KICAgICAgdyA9IGRbaV07DQogICAgICB3cyA9IHcgKyAnJzsNCiAgICAgIGsgPSBMT0dfQkFTRSAtIHdzLmxlbmd0aDsNCiAgICAgIGlmIChrKSBzdHIgKz0gZ2V0WmVyb1N0cmluZyhrKTsNCiAgICB9IGVsc2UgaWYgKHcgPT09IDApIHsNCiAgICAgIHJldHVybiAnMCc7DQogICAgfQ0KDQogICAgLy8gUmVtb3ZlIHRyYWlsaW5nIHplcm9zIG9mIGxhc3Qgdy4NCiAgICBmb3IgKDsgdyAlIDEwID09PSAwOykgdyAvPSAxMDsNCg0KICAgIHJldHVybiBzdHIgKyB3Ow0KICB9DQoNCg0KICBmdW5jdGlvbiBjaGVja0ludDMyKGksIG1pbiwgbWF4KSB7DQogICAgaWYgKGkgIT09IH5+aSB8fCBpIDwgbWluIHx8IGkgPiBtYXgpIHsNCiAgICAgIHRocm93IEVycm9yKGludmFsaWRBcmd1bWVudCArIGkpOw0KICAgIH0NCiAgfQ0KDQoNCiAgLyoNCiAgICogQ2hlY2sgNSByb3VuZGluZyBkaWdpdHMgaWYgYHJlcGVhdGluZ2AgaXMgbnVsbCwgNCBvdGhlcndpc2UuDQogICAqIGByZXBlYXRpbmcgPT0gbnVsbGAgaWYgY2FsbGVyIGlzIGBsb2dgIG9yIGBwb3dgLA0KICAgKiBgcmVwZWF0aW5nICE9IG51bGxgIGlmIGNhbGxlciBpcyBgbmF0dXJhbExvZ2FyaXRobWAgb3IgYG5hdHVyYWxFeHBvbmVudGlhbGAuDQogICAqLw0KICBmdW5jdGlvbiBjaGVja1JvdW5kaW5nRGlnaXRzKGQsIGksIHJtLCByZXBlYXRpbmcpIHsNCiAgICB2YXIgZGksIGssIHIsIHJkOw0KDQogICAgLy8gR2V0IHRoZSBsZW5ndGggb2YgdGhlIGZpcnN0IHdvcmQgb2YgdGhlIGFycmF5IGQuDQogICAgZm9yIChrID0gZFswXTsgayA+PSAxMDsgayAvPSAxMCkgLS1pOw0KDQogICAgLy8gSXMgdGhlIHJvdW5kaW5nIGRpZ2l0IGluIHRoZSBmaXJzdCB3b3JkIG9mIGQ/DQogICAgaWYgKC0taSA8IDApIHsNCiAgICAgIGkgKz0gTE9HX0JBU0U7DQogICAgICBkaSA9IDA7DQogICAgfSBlbHNlIHsNCiAgICAgIGRpID0gTWF0aC5jZWlsKChpICsgMSkgLyBMT0dfQkFTRSk7DQogICAgICBpICU9IExPR19CQVNFOw0KICAgIH0NCg0KICAgIC8vIGkgaXMgdGhlIGluZGV4ICgwIC0gNikgb2YgdGhlIHJvdW5kaW5nIGRpZ2l0Lg0KICAgIC8vIEUuZy4gaWYgd2l0aGluIHRoZSB3b3JkIDM0ODc1NjMgdGhlIGZpcnN0IHJvdW5kaW5nIGRpZ2l0IGlzIDUsDQogICAgLy8gdGhlbiBpID0gNCwgayA9IDEwMDAsIHJkID0gMzQ4NzU2MyAlIDEwMDAgPSA1NjMNCiAgICBrID0gbWF0aHBvdygxMCwgTE9HX0JBU0UgLSBpKTsNCiAgICByZCA9IGRbZGldICUgayB8IDA7DQoNCiAgICBpZiAocmVwZWF0aW5nID09IG51bGwpIHsNCiAgICAgIGlmIChpIDwgMykgew0KICAgICAgICBpZiAoaSA9PSAwKSByZCA9IHJkIC8gMTAwIHwgMDsNCiAgICAgICAgZWxzZSBpZiAoaSA9PSAxKSByZCA9IHJkIC8gMTAgfCAwOw0KICAgICAgICByID0gcm0gPCA0ICYmIHJkID09IDk5OTk5IHx8IHJtID4gMyAmJiByZCA9PSA0OTk5OSB8fCByZCA9PSA1MDAwMCB8fCByZCA9PSAwOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgciA9IChybSA8IDQgJiYgcmQgKyAxID09IGsgfHwgcm0gPiAzICYmIHJkICsgMSA9PSBrIC8gMikgJiYNCiAgICAgICAgICAoZFtkaSArIDFdIC8gayAvIDEwMCB8IDApID09IG1hdGhwb3coMTAsIGkgLSAyKSAtIDEgfHwNCiAgICAgICAgICAgIChyZCA9PSBrIC8gMiB8fCByZCA9PSAwKSAmJiAoZFtkaSArIDFdIC8gayAvIDEwMCB8IDApID09IDA7DQogICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgIGlmIChpIDwgNCkgew0KICAgICAgICBpZiAoaSA9PSAwKSByZCA9IHJkIC8gMTAwMCB8IDA7DQogICAgICAgIGVsc2UgaWYgKGkgPT0gMSkgcmQgPSByZCAvIDEwMCB8IDA7DQogICAgICAgIGVsc2UgaWYgKGkgPT0gMikgcmQgPSByZCAvIDEwIHwgMDsNCiAgICAgICAgciA9IChyZXBlYXRpbmcgfHwgcm0gPCA0KSAmJiByZCA9PSA5OTk5IHx8ICFyZXBlYXRpbmcgJiYgcm0gPiAzICYmIHJkID09IDQ5OTk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICByID0gKChyZXBlYXRpbmcgfHwgcm0gPCA0KSAmJiByZCArIDEgPT0gayB8fA0KICAgICAgICAoIXJlcGVhdGluZyAmJiBybSA+IDMpICYmIHJkICsgMSA9PSBrIC8gMikgJiYNCiAgICAgICAgICAoZFtkaSArIDFdIC8gayAvIDEwMDAgfCAwKSA9PSBtYXRocG93KDEwLCBpIC0gMykgLSAxOw0KICAgICAgfQ0KICAgIH0NCg0KICAgIHJldHVybiByOw0KICB9DQoNCg0KICAvLyBDb252ZXJ0IHN0cmluZyBvZiBgYmFzZUluYCB0byBhbiBhcnJheSBvZiBudW1iZXJzIG9mIGBiYXNlT3V0YC4NCiAgLy8gRWcuIGNvbnZlcnRCYXNlKCcyNTUnLCAxMCwgMTYpIHJldHVybnMgWzE1LCAxNV0uDQogIC8vIEVnLiBjb252ZXJ0QmFzZSgnZmYnLCAxNiwgMTApIHJldHVybnMgWzIsIDUsIDVdLg0KICBmdW5jdGlvbiBjb252ZXJ0QmFzZShzdHIsIGJhc2VJbiwgYmFzZU91dCkgew0KICAgIHZhciBqLA0KICAgICAgYXJyID0gWzBdLA0KICAgICAgYXJyTCwNCiAgICAgIGkgPSAwLA0KICAgICAgc3RyTCA9IHN0ci5sZW5ndGg7DQoNCiAgICBmb3IgKDsgaSA8IHN0ckw7KSB7DQogICAgICBmb3IgKGFyckwgPSBhcnIubGVuZ3RoOyBhcnJMLS07KSBhcnJbYXJyTF0gKj0gYmFzZUluOw0KICAgICAgYXJyWzBdICs9IE5VTUVSQUxTLmluZGV4T2Yoc3RyLmNoYXJBdChpKyspKTsNCiAgICAgIGZvciAoaiA9IDA7IGogPCBhcnIubGVuZ3RoOyBqKyspIHsNCiAgICAgICAgaWYgKGFycltqXSA+IGJhc2VPdXQgLSAxKSB7DQogICAgICAgICAgaWYgKGFycltqICsgMV0gPT09IHZvaWQgMCkgYXJyW2ogKyAxXSA9IDA7DQogICAgICAgICAgYXJyW2ogKyAxXSArPSBhcnJbal0gLyBiYXNlT3V0IHwgMDsNCiAgICAgICAgICBhcnJbal0gJT0gYmFzZU91dDsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCg0KICAgIHJldHVybiBhcnIucmV2ZXJzZSgpOw0KICB9DQoNCg0KICAvKg0KICAgKiBjb3MoeCkgPSAxIC0geF4yLzIhICsgeF40LzQhIC0gLi4uDQogICAqIHx4fCA8IHBpLzINCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGNvc2luZShDdG9yLCB4KSB7DQogICAgdmFyIGssIGxlbiwgeTsNCg0KICAgIGlmICh4LmlzWmVybygpKSByZXR1cm4geDsNCg0KICAgIC8vIEFyZ3VtZW50IHJlZHVjdGlvbjogY29zKDR4KSA9IDgqKGNvc140KHgpIC0gY29zXjIoeCkpICsgMQ0KICAgIC8vIGkuZS4gY29zKHgpID0gOCooY29zXjQoeC80KSAtIGNvc14yKHgvNCkpICsgMQ0KDQogICAgLy8gRXN0aW1hdGUgdGhlIG9wdGltdW0gbnVtYmVyIG9mIHRpbWVzIHRvIHVzZSB0aGUgYXJndW1lbnQgcmVkdWN0aW9uLg0KICAgIGxlbiA9IHguZC5sZW5ndGg7DQogICAgaWYgKGxlbiA8IDMyKSB7DQogICAgICBrID0gTWF0aC5jZWlsKGxlbiAvIDMpOw0KICAgICAgeSA9ICgxIC8gdGlueVBvdyg0LCBrKSkudG9TdHJpbmcoKTsNCiAgICB9IGVsc2Ugew0KICAgICAgayA9IDE2Ow0KICAgICAgeSA9ICcyLjMyODMwNjQzNjUzODY5NjI4OTA2MjVlLTEwJzsNCiAgICB9DQoNCiAgICBDdG9yLnByZWNpc2lvbiArPSBrOw0KDQogICAgeCA9IHRheWxvclNlcmllcyhDdG9yLCAxLCB4LnRpbWVzKHkpLCBuZXcgQ3RvcigxKSk7DQoNCiAgICAvLyBSZXZlcnNlIGFyZ3VtZW50IHJlZHVjdGlvbg0KICAgIGZvciAodmFyIGkgPSBrOyBpLS07KSB7DQogICAgICB2YXIgY29zMnggPSB4LnRpbWVzKHgpOw0KICAgICAgeCA9IGNvczJ4LnRpbWVzKGNvczJ4KS5taW51cyhjb3MyeCkudGltZXMoOCkucGx1cygxKTsNCiAgICB9DQoNCiAgICBDdG9yLnByZWNpc2lvbiAtPSBrOw0KDQogICAgcmV0dXJuIHg7DQogIH0NCg0KDQogIC8qDQogICAqIFBlcmZvcm0gZGl2aXNpb24gaW4gdGhlIHNwZWNpZmllZCBiYXNlLg0KICAgKi8NCiAgdmFyIGRpdmlkZSA9IChmdW5jdGlvbiAoKSB7DQoNCiAgICAvLyBBc3N1bWVzIG5vbi16ZXJvIHggYW5kIGssIGFuZCBoZW5jZSBub24temVybyByZXN1bHQuDQogICAgZnVuY3Rpb24gbXVsdGlwbHlJbnRlZ2VyKHgsIGssIGJhc2UpIHsNCiAgICAgIHZhciB0ZW1wLA0KICAgICAgICBjYXJyeSA9IDAsDQogICAgICAgIGkgPSB4Lmxlbmd0aDsNCg0KICAgICAgZm9yICh4ID0geC5zbGljZSgpOyBpLS07KSB7DQogICAgICAgIHRlbXAgPSB4W2ldICogayArIGNhcnJ5Ow0KICAgICAgICB4W2ldID0gdGVtcCAlIGJhc2UgfCAwOw0KICAgICAgICBjYXJyeSA9IHRlbXAgLyBiYXNlIHwgMDsNCiAgICAgIH0NCg0KICAgICAgaWYgKGNhcnJ5KSB4LnVuc2hpZnQoY2FycnkpOw0KDQogICAgICByZXR1cm4geDsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBjb21wYXJlKGEsIGIsIGFMLCBiTCkgew0KICAgICAgdmFyIGksIHI7DQoNCiAgICAgIGlmIChhTCAhPSBiTCkgew0KICAgICAgICByID0gYUwgPiBiTCA/IDEgOiAtMTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGZvciAoaSA9IHIgPSAwOyBpIDwgYUw7IGkrKykgew0KICAgICAgICAgIGlmIChhW2ldICE9IGJbaV0pIHsNCiAgICAgICAgICAgIHIgPSBhW2ldID4gYltpXSA/IDEgOiAtMTsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KDQogICAgICByZXR1cm4gcjsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBzdWJ0cmFjdChhLCBiLCBhTCwgYmFzZSkgew0KICAgICAgdmFyIGkgPSAwOw0KDQogICAgICAvLyBTdWJ0cmFjdCBiIGZyb20gYS4NCiAgICAgIGZvciAoOyBhTC0tOykgew0KICAgICAgICBhW2FMXSAtPSBpOw0KICAgICAgICBpID0gYVthTF0gPCBiW2FMXSA/IDEgOiAwOw0KICAgICAgICBhW2FMXSA9IGkgKiBiYXNlICsgYVthTF0gLSBiW2FMXTsNCiAgICAgIH0NCg0KICAgICAgLy8gUmVtb3ZlIGxlYWRpbmcgemVyb3MuDQogICAgICBmb3IgKDsgIWFbMF0gJiYgYS5sZW5ndGggPiAxOykgYS5zaGlmdCgpOw0KICAgIH0NCg0KICAgIHJldHVybiBmdW5jdGlvbiAoeCwgeSwgcHIsIHJtLCBkcCwgYmFzZSkgew0KICAgICAgdmFyIGNtcCwgZSwgaSwgaywgbG9nQmFzZSwgbW9yZSwgcHJvZCwgcHJvZEwsIHEsIHFkLCByZW0sIHJlbUwsIHJlbTAsIHNkLCB0LCB4aSwgeEwsIHlkMCwNCiAgICAgICAgeUwsIHl6LA0KICAgICAgICBDdG9yID0geC5jb25zdHJ1Y3RvciwNCiAgICAgICAgc2lnbiA9IHgucyA9PSB5LnMgPyAxIDogLTEsDQogICAgICAgIHhkID0geC5kLA0KICAgICAgICB5ZCA9IHkuZDsNCg0KICAgICAgLy8gRWl0aGVyIE5hTiwgSW5maW5pdHkgb3IgMD8NCiAgICAgIGlmICgheGQgfHwgIXhkWzBdIHx8ICF5ZCB8fCAheWRbMF0pIHsNCg0KICAgICAgICByZXR1cm4gbmV3IEN0b3IoLy8gUmV0dXJuIE5hTiBpZiBlaXRoZXIgTmFOLCBvciBib3RoIEluZmluaXR5IG9yIDAuDQogICAgICAgICAgIXgucyB8fCAheS5zIHx8ICh4ZCA/IHlkICYmIHhkWzBdID09IHlkWzBdIDogIXlkKSA/IE5hTiA6DQoNCiAgICAgICAgICAvLyBSZXR1cm4gwrEwIGlmIHggaXMgMCBvciB5IGlzIMKxSW5maW5pdHksIG9yIHJldHVybiDCsUluZmluaXR5IGFzIHkgaXMgMC4NCiAgICAgICAgICB4ZCAmJiB4ZFswXSA9PSAwIHx8ICF5ZCA/IHNpZ24gKiAwIDogc2lnbiAvIDApOw0KICAgICAgfQ0KDQogICAgICBpZiAoYmFzZSkgew0KICAgICAgICBsb2dCYXNlID0gMTsNCiAgICAgICAgZSA9IHguZSAtIHkuZTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGJhc2UgPSBCQVNFOw0KICAgICAgICBsb2dCYXNlID0gTE9HX0JBU0U7DQogICAgICAgIGUgPSBtYXRoZmxvb3IoeC5lIC8gbG9nQmFzZSkgLSBtYXRoZmxvb3IoeS5lIC8gbG9nQmFzZSk7DQogICAgICB9DQoNCiAgICAgIHlMID0geWQubGVuZ3RoOw0KICAgICAgeEwgPSB4ZC5sZW5ndGg7DQogICAgICBxID0gbmV3IEN0b3Ioc2lnbik7DQogICAgICBxZCA9IHEuZCA9IFtdOw0KDQogICAgICAvLyBSZXN1bHQgZXhwb25lbnQgbWF5IGJlIG9uZSBsZXNzIHRoYW4gZS4NCiAgICAgIC8vIFRoZSBkaWdpdCBhcnJheSBvZiBhIERlY2ltYWwgZnJvbSB0b1N0cmluZ0JpbmFyeSBtYXkgaGF2ZSB0cmFpbGluZyB6ZXJvcy4NCiAgICAgIGZvciAoaSA9IDA7IHlkW2ldID09ICh4ZFtpXSB8fCAwKTsgaSsrKTsNCg0KICAgICAgaWYgKHlkW2ldID4gKHhkW2ldIHx8IDApKSBlLS07DQoNCiAgICAgIGlmIChwciA9PSBudWxsKSB7DQogICAgICAgIHNkID0gcHIgPSBDdG9yLnByZWNpc2lvbjsNCiAgICAgICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KICAgICAgfSBlbHNlIGlmIChkcCkgew0KICAgICAgICBzZCA9IHByICsgKHguZSAtIHkuZSkgKyAxOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgc2QgPSBwcjsNCiAgICAgIH0NCg0KICAgICAgaWYgKHNkIDwgMCkgew0KICAgICAgICBxZC5wdXNoKDEpOw0KICAgICAgICBtb3JlID0gdHJ1ZTsNCiAgICAgIH0gZWxzZSB7DQoNCiAgICAgICAgLy8gQ29udmVydCBwcmVjaXNpb24gaW4gbnVtYmVyIG9mIGJhc2UgMTAgZGlnaXRzIHRvIGJhc2UgMWU3IGRpZ2l0cy4NCiAgICAgICAgc2QgPSBzZCAvIGxvZ0Jhc2UgKyAyIHwgMDsNCiAgICAgICAgaSA9IDA7DQoNCiAgICAgICAgLy8gZGl2aXNvciA8IDFlNw0KICAgICAgICBpZiAoeUwgPT0gMSkgew0KICAgICAgICAgIGsgPSAwOw0KICAgICAgICAgIHlkID0geWRbMF07DQogICAgICAgICAgc2QrKzsNCg0KICAgICAgICAgIC8vIGsgaXMgdGhlIGNhcnJ5Lg0KICAgICAgICAgIGZvciAoOyAoaSA8IHhMIHx8IGspICYmIHNkLS07IGkrKykgew0KICAgICAgICAgICAgdCA9IGsgKiBiYXNlICsgKHhkW2ldIHx8IDApOw0KICAgICAgICAgICAgcWRbaV0gPSB0IC8geWQgfCAwOw0KICAgICAgICAgICAgayA9IHQgJSB5ZCB8IDA7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgbW9yZSA9IGsgfHwgaSA8IHhMOw0KDQogICAgICAgIC8vIGRpdmlzb3IgPj0gMWU3DQogICAgICAgIH0gZWxzZSB7DQoNCiAgICAgICAgICAvLyBOb3JtYWxpc2UgeGQgYW5kIHlkIHNvIGhpZ2hlc3Qgb3JkZXIgZGlnaXQgb2YgeWQgaXMgPj0gYmFzZS8yDQogICAgICAgICAgayA9IGJhc2UgLyAoeWRbMF0gKyAxKSB8IDA7DQoNCiAgICAgICAgICBpZiAoayA+IDEpIHsNCiAgICAgICAgICAgIHlkID0gbXVsdGlwbHlJbnRlZ2VyKHlkLCBrLCBiYXNlKTsNCiAgICAgICAgICAgIHhkID0gbXVsdGlwbHlJbnRlZ2VyKHhkLCBrLCBiYXNlKTsNCiAgICAgICAgICAgIHlMID0geWQubGVuZ3RoOw0KICAgICAgICAgICAgeEwgPSB4ZC5sZW5ndGg7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgeGkgPSB5TDsNCiAgICAgICAgICByZW0gPSB4ZC5zbGljZSgwLCB5TCk7DQogICAgICAgICAgcmVtTCA9IHJlbS5sZW5ndGg7DQoNCiAgICAgICAgICAvLyBBZGQgemVyb3MgdG8gbWFrZSByZW1haW5kZXIgYXMgbG9uZyBhcyBkaXZpc29yLg0KICAgICAgICAgIGZvciAoOyByZW1MIDwgeUw7KSByZW1bcmVtTCsrXSA9IDA7DQoNCiAgICAgICAgICB5eiA9IHlkLnNsaWNlKCk7DQogICAgICAgICAgeXoudW5zaGlmdCgwKTsNCiAgICAgICAgICB5ZDAgPSB5ZFswXTsNCg0KICAgICAgICAgIGlmICh5ZFsxXSA+PSBiYXNlIC8gMikgKyt5ZDA7DQoNCiAgICAgICAgICBkbyB7DQogICAgICAgICAgICBrID0gMDsNCg0KICAgICAgICAgICAgLy8gQ29tcGFyZSBkaXZpc29yIGFuZCByZW1haW5kZXIuDQogICAgICAgICAgICBjbXAgPSBjb21wYXJlKHlkLCByZW0sIHlMLCByZW1MKTsNCg0KICAgICAgICAgICAgLy8gSWYgZGl2aXNvciA8IHJlbWFpbmRlci4NCiAgICAgICAgICAgIGlmIChjbXAgPCAwKSB7DQoNCiAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRyaWFsIGRpZ2l0LCBrLg0KICAgICAgICAgICAgICByZW0wID0gcmVtWzBdOw0KICAgICAgICAgICAgICBpZiAoeUwgIT0gcmVtTCkgcmVtMCA9IHJlbTAgKiBiYXNlICsgKHJlbVsxXSB8fCAwKTsNCg0KICAgICAgICAgICAgICAvLyBrIHdpbGwgYmUgaG93IG1hbnkgdGltZXMgdGhlIGRpdmlzb3IgZ29lcyBpbnRvIHRoZSBjdXJyZW50IHJlbWFpbmRlci4NCiAgICAgICAgICAgICAgayA9IHJlbTAgLyB5ZDAgfCAwOw0KDQogICAgICAgICAgICAgIC8vICBBbGdvcml0aG06DQogICAgICAgICAgICAgIC8vICAxLiBwcm9kdWN0ID0gZGl2aXNvciAqIHRyaWFsIGRpZ2l0IChrKQ0KICAgICAgICAgICAgICAvLyAgMi4gaWYgcHJvZHVjdCA+IHJlbWFpbmRlcjogcHJvZHVjdCAtPSBkaXZpc29yLCBrLS0NCiAgICAgICAgICAgICAgLy8gIDMuIHJlbWFpbmRlciAtPSBwcm9kdWN0DQogICAgICAgICAgICAgIC8vICA0LiBpZiBwcm9kdWN0IHdhcyA8IHJlbWFpbmRlciBhdCAyOg0KICAgICAgICAgICAgICAvLyAgICA1LiBjb21wYXJlIG5ldyByZW1haW5kZXIgYW5kIGRpdmlzb3INCiAgICAgICAgICAgICAgLy8gICAgNi4gSWYgcmVtYWluZGVyID4gZGl2aXNvcjogcmVtYWluZGVyIC09IGRpdmlzb3IsIGsrKw0KDQogICAgICAgICAgICAgIGlmIChrID4gMSkgew0KICAgICAgICAgICAgICAgIGlmIChrID49IGJhc2UpIGsgPSBiYXNlIC0gMTsNCg0KICAgICAgICAgICAgICAgIC8vIHByb2R1Y3QgPSBkaXZpc29yICogdHJpYWwgZGlnaXQuDQogICAgICAgICAgICAgICAgcHJvZCA9IG11bHRpcGx5SW50ZWdlcih5ZCwgaywgYmFzZSk7DQogICAgICAgICAgICAgICAgcHJvZEwgPSBwcm9kLmxlbmd0aDsNCiAgICAgICAgICAgICAgICByZW1MID0gcmVtLmxlbmd0aDsNCg0KICAgICAgICAgICAgICAgIC8vIENvbXBhcmUgcHJvZHVjdCBhbmQgcmVtYWluZGVyLg0KICAgICAgICAgICAgICAgIGNtcCA9IGNvbXBhcmUocHJvZCwgcmVtLCBwcm9kTCwgcmVtTCk7DQoNCiAgICAgICAgICAgICAgICAvLyBwcm9kdWN0ID4gcmVtYWluZGVyLg0KICAgICAgICAgICAgICAgIGlmIChjbXAgPT0gMSkgew0KICAgICAgICAgICAgICAgICAgay0tOw0KDQogICAgICAgICAgICAgICAgICAvLyBTdWJ0cmFjdCBkaXZpc29yIGZyb20gcHJvZHVjdC4NCiAgICAgICAgICAgICAgICAgIHN1YnRyYWN0KHByb2QsIHlMIDwgcHJvZEwgPyB5eiA6IHlkLCBwcm9kTCwgYmFzZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICB9IGVsc2Ugew0KDQogICAgICAgICAgICAgICAgLy8gY21wIGlzIC0xLg0KICAgICAgICAgICAgICAgIC8vIElmIGsgaXMgMCwgdGhlcmUgaXMgbm8gbmVlZCB0byBjb21wYXJlIHlkIGFuZCByZW0gYWdhaW4gYmVsb3csIHNvIGNoYW5nZSBjbXAgdG8gMQ0KICAgICAgICAgICAgICAgIC8vIHRvIGF2b2lkIGl0LiBJZiBrIGlzIDEgdGhlcmUgaXMgYSBuZWVkIHRvIGNvbXBhcmUgeWQgYW5kIHJlbSBhZ2FpbiBiZWxvdy4NCiAgICAgICAgICAgICAgICBpZiAoayA9PSAwKSBjbXAgPSBrID0gMTsNCiAgICAgICAgICAgICAgICBwcm9kID0geWQuc2xpY2UoKTsNCiAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgIHByb2RMID0gcHJvZC5sZW5ndGg7DQogICAgICAgICAgICAgIGlmIChwcm9kTCA8IHJlbUwpIHByb2QudW5zaGlmdCgwKTsNCg0KICAgICAgICAgICAgICAvLyBTdWJ0cmFjdCBwcm9kdWN0IGZyb20gcmVtYWluZGVyLg0KICAgICAgICAgICAgICBzdWJ0cmFjdChyZW0sIHByb2QsIHJlbUwsIGJhc2UpOw0KDQogICAgICAgICAgICAgIC8vIElmIHByb2R1Y3Qgd2FzIDwgcHJldmlvdXMgcmVtYWluZGVyLg0KICAgICAgICAgICAgICBpZiAoY21wID09IC0xKSB7DQogICAgICAgICAgICAgICAgcmVtTCA9IHJlbS5sZW5ndGg7DQoNCiAgICAgICAgICAgICAgICAvLyBDb21wYXJlIGRpdmlzb3IgYW5kIG5ldyByZW1haW5kZXIuDQogICAgICAgICAgICAgICAgY21wID0gY29tcGFyZSh5ZCwgcmVtLCB5TCwgcmVtTCk7DQoNCiAgICAgICAgICAgICAgICAvLyBJZiBkaXZpc29yIDwgbmV3IHJlbWFpbmRlciwgc3VidHJhY3QgZGl2aXNvciBmcm9tIHJlbWFpbmRlci4NCiAgICAgICAgICAgICAgICBpZiAoY21wIDwgMSkgew0KICAgICAgICAgICAgICAgICAgaysrOw0KDQogICAgICAgICAgICAgICAgICAvLyBTdWJ0cmFjdCBkaXZpc29yIGZyb20gcmVtYWluZGVyLg0KICAgICAgICAgICAgICAgICAgc3VidHJhY3QocmVtLCB5TCA8IHJlbUwgPyB5eiA6IHlkLCByZW1MLCBiYXNlKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICByZW1MID0gcmVtLmxlbmd0aDsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoY21wID09PSAwKSB7DQogICAgICAgICAgICAgIGsrKzsNCiAgICAgICAgICAgICAgcmVtID0gWzBdOw0KICAgICAgICAgICAgfSAgICAvLyBpZiBjbXAgPT09IDEsIGsgd2lsbCBiZSAwDQoNCiAgICAgICAgICAgIC8vIEFkZCB0aGUgbmV4dCBkaWdpdCwgaywgdG8gdGhlIHJlc3VsdCBhcnJheS4NCiAgICAgICAgICAgIHFkW2krK10gPSBrOw0KDQogICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHJlbWFpbmRlci4NCiAgICAgICAgICAgIGlmIChjbXAgJiYgcmVtWzBdKSB7DQogICAgICAgICAgICAgIHJlbVtyZW1MKytdID0geGRbeGldIHx8IDA7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICByZW0gPSBbeGRbeGldXTsNCiAgICAgICAgICAgICAgcmVtTCA9IDE7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICB9IHdoaWxlICgoeGkrKyA8IHhMIHx8IHJlbVswXSAhPT0gdm9pZCAwKSAmJiBzZC0tKTsNCg0KICAgICAgICAgIG1vcmUgPSByZW1bMF0gIT09IHZvaWQgMDsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIExlYWRpbmcgemVybz8NCiAgICAgICAgaWYgKCFxZFswXSkgcWQuc2hpZnQoKTsNCiAgICAgIH0NCg0KICAgICAgLy8gbG9nQmFzZSBpcyAxIHdoZW4gZGl2aWRlIGlzIGJlaW5nIHVzZWQgZm9yIGJhc2UgY29udmVyc2lvbi4NCiAgICAgIGlmIChsb2dCYXNlID09IDEpIHsNCiAgICAgICAgcS5lID0gZTsNCiAgICAgICAgaW5leGFjdCA9IG1vcmU7DQogICAgICB9IGVsc2Ugew0KDQogICAgICAgIC8vIFRvIGNhbGN1bGF0ZSBxLmUsIGZpcnN0IGdldCB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBvZiBxZFswXS4NCiAgICAgICAgZm9yIChpID0gMSwgayA9IHFkWzBdOyBrID49IDEwOyBrIC89IDEwKSBpKys7DQogICAgICAgIHEuZSA9IGkgKyBlICogbG9nQmFzZSAtIDE7DQoNCiAgICAgICAgZmluYWxpc2UocSwgZHAgPyBwciArIHEuZSArIDEgOiBwciwgcm0sIG1vcmUpOw0KICAgICAgfQ0KDQogICAgICByZXR1cm4gcTsNCiAgICB9Ow0KICB9KSgpOw0KDQoNCiAgLyoNCiAgICogUm91bmQgYHhgIHRvIGBzZGAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJtYC4NCiAgICogQ2hlY2sgZm9yIG92ZXIvdW5kZXItZmxvdy4NCiAgICovDQogICBmdW5jdGlvbiBmaW5hbGlzZSh4LCBzZCwgcm0sIGlzVHJ1bmNhdGVkKSB7DQogICAgdmFyIGRpZ2l0cywgaSwgaiwgaywgcmQsIHJvdW5kVXAsIHcsIHhkLCB4ZGksDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIC8vIERvbid0IHJvdW5kIGlmIHNkIGlzIG51bGwgb3IgdW5kZWZpbmVkLg0KICAgIG91dDogaWYgKHNkICE9IG51bGwpIHsNCiAgICAgIHhkID0geC5kOw0KDQogICAgICAvLyBJbmZpbml0eS9OYU4uDQogICAgICBpZiAoIXhkKSByZXR1cm4geDsNCg0KICAgICAgLy8gcmQ6IHRoZSByb3VuZGluZyBkaWdpdCwgaS5lLiB0aGUgZGlnaXQgYWZ0ZXIgdGhlIGRpZ2l0IHRoYXQgbWF5IGJlIHJvdW5kZWQgdXAuDQogICAgICAvLyB3OiB0aGUgd29yZCBvZiB4ZCBjb250YWluaW5nIHJkLCBhIGJhc2UgMWU3IG51bWJlci4NCiAgICAgIC8vIHhkaTogdGhlIGluZGV4IG9mIHcgd2l0aGluIHhkLg0KICAgICAgLy8gZGlnaXRzOiB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBvZiB3Lg0KICAgICAgLy8gaTogd2hhdCB3b3VsZCBiZSB0aGUgaW5kZXggb2YgcmQgd2l0aGluIHcgaWYgYWxsIHRoZSBudW1iZXJzIHdlcmUgNyBkaWdpdHMgbG9uZyAoaS5lLiBpZg0KICAgICAgLy8gdGhleSBoYWQgbGVhZGluZyB6ZXJvcykNCiAgICAgIC8vIGo6IGlmID4gMCwgdGhlIGFjdHVhbCBpbmRleCBvZiByZCB3aXRoaW4gdyAoaWYgPCAwLCByZCBpcyBhIGxlYWRpbmcgemVybykuDQoNCiAgICAgIC8vIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBmaXJzdCB3b3JkIG9mIHRoZSBkaWdpdHMgYXJyYXkgeGQuDQogICAgICBmb3IgKGRpZ2l0cyA9IDEsIGsgPSB4ZFswXTsgayA+PSAxMDsgayAvPSAxMCkgZGlnaXRzKys7DQogICAgICBpID0gc2QgLSBkaWdpdHM7DQoNCiAgICAgIC8vIElzIHRoZSByb3VuZGluZyBkaWdpdCBpbiB0aGUgZmlyc3Qgd29yZCBvZiB4ZD8NCiAgICAgIGlmIChpIDwgMCkgew0KICAgICAgICBpICs9IExPR19CQVNFOw0KICAgICAgICBqID0gc2Q7DQogICAgICAgIHcgPSB4ZFt4ZGkgPSAwXTsNCg0KICAgICAgICAvLyBHZXQgdGhlIHJvdW5kaW5nIGRpZ2l0IGF0IGluZGV4IGogb2Ygdy4NCiAgICAgICAgcmQgPSB3IC8gbWF0aHBvdygxMCwgZGlnaXRzIC0gaiAtIDEpICUgMTAgfCAwOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgeGRpID0gTWF0aC5jZWlsKChpICsgMSkgLyBMT0dfQkFTRSk7DQogICAgICAgIGsgPSB4ZC5sZW5ndGg7DQogICAgICAgIGlmICh4ZGkgPj0gaykgew0KICAgICAgICAgIGlmIChpc1RydW5jYXRlZCkgew0KDQogICAgICAgICAgICAvLyBOZWVkZWQgYnkgYG5hdHVyYWxFeHBvbmVudGlhbGAsIGBuYXR1cmFsTG9nYXJpdGhtYCBhbmQgYHNxdWFyZVJvb3RgLg0KICAgICAgICAgICAgZm9yICg7IGsrKyA8PSB4ZGk7KSB4ZC5wdXNoKDApOw0KICAgICAgICAgICAgdyA9IHJkID0gMDsNCiAgICAgICAgICAgIGRpZ2l0cyA9IDE7DQogICAgICAgICAgICBpICU9IExPR19CQVNFOw0KICAgICAgICAgICAgaiA9IGkgLSBMT0dfQkFTRSArIDE7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGJyZWFrIG91dDsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgdyA9IGsgPSB4ZFt4ZGldOw0KDQogICAgICAgICAgLy8gR2V0IHRoZSBudW1iZXIgb2YgZGlnaXRzIG9mIHcuDQogICAgICAgICAgZm9yIChkaWdpdHMgPSAxOyBrID49IDEwOyBrIC89IDEwKSBkaWdpdHMrKzsNCg0KICAgICAgICAgIC8vIEdldCB0aGUgaW5kZXggb2YgcmQgd2l0aGluIHcuDQogICAgICAgICAgaSAlPSBMT0dfQkFTRTsNCg0KICAgICAgICAgIC8vIEdldCB0aGUgaW5kZXggb2YgcmQgd2l0aGluIHcsIGFkanVzdGVkIGZvciBsZWFkaW5nIHplcm9zLg0KICAgICAgICAgIC8vIFRoZSBudW1iZXIgb2YgbGVhZGluZyB6ZXJvcyBvZiB3IGlzIGdpdmVuIGJ5IExPR19CQVNFIC0gZGlnaXRzLg0KICAgICAgICAgIGogPSBpIC0gTE9HX0JBU0UgKyBkaWdpdHM7DQoNCiAgICAgICAgICAvLyBHZXQgdGhlIHJvdW5kaW5nIGRpZ2l0IGF0IGluZGV4IGogb2Ygdy4NCiAgICAgICAgICByZCA9IGogPCAwID8gMCA6IHcgLyBtYXRocG93KDEwLCBkaWdpdHMgLSBqIC0gMSkgJSAxMCB8IDA7DQogICAgICAgIH0NCiAgICAgIH0NCg0KICAgICAgLy8gQXJlIHRoZXJlIGFueSBub24temVybyBkaWdpdHMgYWZ0ZXIgdGhlIHJvdW5kaW5nIGRpZ2l0Pw0KICAgICAgaXNUcnVuY2F0ZWQgPSBpc1RydW5jYXRlZCB8fCBzZCA8IDAgfHwNCiAgICAgICAgeGRbeGRpICsgMV0gIT09IHZvaWQgMCB8fCAoaiA8IDAgPyB3IDogdyAlIG1hdGhwb3coMTAsIGRpZ2l0cyAtIGogLSAxKSk7DQoNCiAgICAgIC8vIFRoZSBleHByZXNzaW9uIGB3ICUgbWF0aHBvdygxMCwgZGlnaXRzIC0gaiAtIDEpYCByZXR1cm5zIGFsbCB0aGUgZGlnaXRzIG9mIHcgdG8gdGhlIHJpZ2h0DQogICAgICAvLyBvZiB0aGUgZGlnaXQgYXQgKGxlZnQtdG8tcmlnaHQpIGluZGV4IGosIGUuZy4gaWYgdyBpcyA5MDg3MTQgYW5kIGogaXMgMiwgdGhlIGV4cHJlc3Npb24NCiAgICAgIC8vIHdpbGwgZ2l2ZSA3MTQuDQoNCiAgICAgIHJvdW5kVXAgPSBybSA8IDQNCiAgICAgICAgPyAocmQgfHwgaXNUcnVuY2F0ZWQpICYmIChybSA9PSAwIHx8IHJtID09ICh4LnMgPCAwID8gMyA6IDIpKQ0KICAgICAgICA6IHJkID4gNSB8fCByZCA9PSA1ICYmIChybSA9PSA0IHx8IGlzVHJ1bmNhdGVkIHx8IHJtID09IDYgJiYNCg0KICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGRpZ2l0IHRvIHRoZSBsZWZ0IG9mIHRoZSByb3VuZGluZyBkaWdpdCBpcyBvZGQuDQogICAgICAgICAgKChpID4gMCA/IGogPiAwID8gdyAvIG1hdGhwb3coMTAsIGRpZ2l0cyAtIGopIDogMCA6IHhkW3hkaSAtIDFdKSAlIDEwKSAmIDEgfHwNCiAgICAgICAgICAgIHJtID09ICh4LnMgPCAwID8gOCA6IDcpKTsNCg0KICAgICAgaWYgKHNkIDwgMSB8fCAheGRbMF0pIHsNCiAgICAgICAgeGQubGVuZ3RoID0gMDsNCiAgICAgICAgaWYgKHJvdW5kVXApIHsNCg0KICAgICAgICAgIC8vIENvbnZlcnQgc2QgdG8gZGVjaW1hbCBwbGFjZXMuDQogICAgICAgICAgc2QgLT0geC5lICsgMTsNCg0KICAgICAgICAgIC8vIDEsIDAuMSwgMC4wMSwgMC4wMDEsIDAuMDAwMSBldGMuDQogICAgICAgICAgeGRbMF0gPSBtYXRocG93KDEwLCAoTE9HX0JBU0UgLSBzZCAlIExPR19CQVNFKSAlIExPR19CQVNFKTsNCiAgICAgICAgICB4LmUgPSAtc2QgfHwgMDsNCiAgICAgICAgfSBlbHNlIHsNCg0KICAgICAgICAgIC8vIFplcm8uDQogICAgICAgICAgeGRbMF0gPSB4LmUgPSAwOw0KICAgICAgICB9DQoNCiAgICAgICAgcmV0dXJuIHg7DQogICAgICB9DQoNCiAgICAgIC8vIFJlbW92ZSBleGNlc3MgZGlnaXRzLg0KICAgICAgaWYgKGkgPT0gMCkgew0KICAgICAgICB4ZC5sZW5ndGggPSB4ZGk7DQogICAgICAgIGsgPSAxOw0KICAgICAgICB4ZGktLTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHhkLmxlbmd0aCA9IHhkaSArIDE7DQogICAgICAgIGsgPSBtYXRocG93KDEwLCBMT0dfQkFTRSAtIGkpOw0KDQogICAgICAgIC8vIEUuZy4gNTY3MDAgYmVjb21lcyA1NjAwMCBpZiA3IGlzIHRoZSByb3VuZGluZyBkaWdpdC4NCiAgICAgICAgLy8gaiA+IDAgbWVhbnMgaSA+IG51bWJlciBvZiBsZWFkaW5nIHplcm9zIG9mIHcuDQogICAgICAgIHhkW3hkaV0gPSBqID4gMCA/ICh3IC8gbWF0aHBvdygxMCwgZGlnaXRzIC0gaikgJSBtYXRocG93KDEwLCBqKSB8IDApICogayA6IDA7DQogICAgICB9DQoNCiAgICAgIGlmIChyb3VuZFVwKSB7DQogICAgICAgIGZvciAoOzspIHsNCg0KICAgICAgICAgIC8vIElzIHRoZSBkaWdpdCB0byBiZSByb3VuZGVkIHVwIGluIHRoZSBmaXJzdCB3b3JkIG9mIHhkPw0KICAgICAgICAgIGlmICh4ZGkgPT0gMCkgew0KDQogICAgICAgICAgICAvLyBpIHdpbGwgYmUgdGhlIGxlbmd0aCBvZiB4ZFswXSBiZWZvcmUgayBpcyBhZGRlZC4NCiAgICAgICAgICAgIGZvciAoaSA9IDEsIGogPSB4ZFswXTsgaiA+PSAxMDsgaiAvPSAxMCkgaSsrOw0KICAgICAgICAgICAgaiA9IHhkWzBdICs9IGs7DQogICAgICAgICAgICBmb3IgKGsgPSAxOyBqID49IDEwOyBqIC89IDEwKSBrKys7DQoNCiAgICAgICAgICAgIC8vIGlmIGkgIT0gayB0aGUgbGVuZ3RoIGhhcyBpbmNyZWFzZWQuDQogICAgICAgICAgICBpZiAoaSAhPSBrKSB7DQogICAgICAgICAgICAgIHguZSsrOw0KICAgICAgICAgICAgICBpZiAoeGRbMF0gPT0gQkFTRSkgeGRbMF0gPSAxOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgeGRbeGRpXSArPSBrOw0KICAgICAgICAgICAgaWYgKHhkW3hkaV0gIT0gQkFTRSkgYnJlYWs7DQogICAgICAgICAgICB4ZFt4ZGktLV0gPSAwOw0KICAgICAgICAgICAgayA9IDE7DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQoNCiAgICAgIC8vIFJlbW92ZSB0cmFpbGluZyB6ZXJvcy4NCiAgICAgIGZvciAoaSA9IHhkLmxlbmd0aDsgeGRbLS1pXSA9PT0gMDspIHhkLnBvcCgpOw0KICAgIH0NCg0KICAgIGlmIChleHRlcm5hbCkgew0KDQogICAgICAvLyBPdmVyZmxvdz8NCiAgICAgIGlmICh4LmUgPiBDdG9yLm1heEUpIHsNCg0KICAgICAgICAvLyBJbmZpbml0eS4NCiAgICAgICAgeC5kID0gbnVsbDsNCiAgICAgICAgeC5lID0gTmFOOw0KDQogICAgICAvLyBVbmRlcmZsb3c/DQogICAgICB9IGVsc2UgaWYgKHguZSA8IEN0b3IubWluRSkgew0KDQogICAgICAgIC8vIFplcm8uDQogICAgICAgIHguZSA9IDA7DQogICAgICAgIHguZCA9IFswXTsNCiAgICAgICAgLy8gQ3Rvci51bmRlcmZsb3cgPSB0cnVlOw0KICAgICAgfSAvLyBlbHNlIEN0b3IudW5kZXJmbG93ID0gZmFsc2U7DQogICAgfQ0KDQogICAgcmV0dXJuIHg7DQogIH0NCg0KDQogIGZ1bmN0aW9uIGZpbml0ZVRvU3RyaW5nKHgsIGlzRXhwLCBzZCkgew0KICAgIGlmICgheC5pc0Zpbml0ZSgpKSByZXR1cm4gbm9uRmluaXRlVG9TdHJpbmcoeCk7DQogICAgdmFyIGssDQogICAgICBlID0geC5lLA0KICAgICAgc3RyID0gZGlnaXRzVG9TdHJpbmcoeC5kKSwNCiAgICAgIGxlbiA9IHN0ci5sZW5ndGg7DQoNCiAgICBpZiAoaXNFeHApIHsNCiAgICAgIGlmIChzZCAmJiAoayA9IHNkIC0gbGVuKSA+IDApIHsNCiAgICAgICAgc3RyID0gc3RyLmNoYXJBdCgwKSArICcuJyArIHN0ci5zbGljZSgxKSArIGdldFplcm9TdHJpbmcoayk7DQogICAgICB9IGVsc2UgaWYgKGxlbiA+IDEpIHsNCiAgICAgICAgc3RyID0gc3RyLmNoYXJBdCgwKSArICcuJyArIHN0ci5zbGljZSgxKTsNCiAgICAgIH0NCg0KICAgICAgc3RyID0gc3RyICsgKHguZSA8IDAgPyAnZScgOiAnZSsnKSArIHguZTsNCiAgICB9IGVsc2UgaWYgKGUgPCAwKSB7DQogICAgICBzdHIgPSAnMC4nICsgZ2V0WmVyb1N0cmluZygtZSAtIDEpICsgc3RyOw0KICAgICAgaWYgKHNkICYmIChrID0gc2QgLSBsZW4pID4gMCkgc3RyICs9IGdldFplcm9TdHJpbmcoayk7DQogICAgfSBlbHNlIGlmIChlID49IGxlbikgew0KICAgICAgc3RyICs9IGdldFplcm9TdHJpbmcoZSArIDEgLSBsZW4pOw0KICAgICAgaWYgKHNkICYmIChrID0gc2QgLSBlIC0gMSkgPiAwKSBzdHIgPSBzdHIgKyAnLicgKyBnZXRaZXJvU3RyaW5nKGspOw0KICAgIH0gZWxzZSB7DQogICAgICBpZiAoKGsgPSBlICsgMSkgPCBsZW4pIHN0ciA9IHN0ci5zbGljZSgwLCBrKSArICcuJyArIHN0ci5zbGljZShrKTsNCiAgICAgIGlmIChzZCAmJiAoayA9IHNkIC0gbGVuKSA+IDApIHsNCiAgICAgICAgaWYgKGUgKyAxID09PSBsZW4pIHN0ciArPSAnLic7DQogICAgICAgIHN0ciArPSBnZXRaZXJvU3RyaW5nKGspOw0KICAgICAgfQ0KICAgIH0NCg0KICAgIHJldHVybiBzdHI7DQogIH0NCg0KDQogIC8vIENhbGN1bGF0ZSB0aGUgYmFzZSAxMCBleHBvbmVudCBmcm9tIHRoZSBiYXNlIDFlNyBleHBvbmVudC4NCiAgZnVuY3Rpb24gZ2V0QmFzZTEwRXhwb25lbnQoZGlnaXRzLCBlKSB7DQogICAgdmFyIHcgPSBkaWdpdHNbMF07DQoNCiAgICAvLyBBZGQgdGhlIG51bWJlciBvZiBkaWdpdHMgb2YgdGhlIGZpcnN0IHdvcmQgb2YgdGhlIGRpZ2l0cyBhcnJheS4NCiAgICBmb3IgKCBlICo9IExPR19CQVNFOyB3ID49IDEwOyB3IC89IDEwKSBlKys7DQogICAgcmV0dXJuIGU7DQogIH0NCg0KDQogIGZ1bmN0aW9uIGdldExuMTAoQ3Rvciwgc2QsIHByKSB7DQogICAgaWYgKHNkID4gTE4xMF9QUkVDSVNJT04pIHsNCg0KICAgICAgLy8gUmVzZXQgZ2xvYmFsIHN0YXRlIGluIGNhc2UgdGhlIGV4Y2VwdGlvbiBpcyBjYXVnaHQuDQogICAgICBleHRlcm5hbCA9IHRydWU7DQogICAgICBpZiAocHIpIEN0b3IucHJlY2lzaW9uID0gcHI7DQogICAgICB0aHJvdyBFcnJvcihwcmVjaXNpb25MaW1pdEV4Y2VlZGVkKTsNCiAgICB9DQogICAgcmV0dXJuIGZpbmFsaXNlKG5ldyBDdG9yKExOMTApLCBzZCwgMSwgdHJ1ZSk7DQogIH0NCg0KDQogIGZ1bmN0aW9uIGdldFBpKEN0b3IsIHNkLCBybSkgew0KICAgIGlmIChzZCA+IFBJX1BSRUNJU0lPTikgdGhyb3cgRXJyb3IocHJlY2lzaW9uTGltaXRFeGNlZWRlZCk7DQogICAgcmV0dXJuIGZpbmFsaXNlKG5ldyBDdG9yKFBJKSwgc2QsIHJtLCB0cnVlKTsNCiAgfQ0KDQoNCiAgZnVuY3Rpb24gZ2V0UHJlY2lzaW9uKGRpZ2l0cykgew0KICAgIHZhciB3ID0gZGlnaXRzLmxlbmd0aCAtIDEsDQogICAgICBsZW4gPSB3ICogTE9HX0JBU0UgKyAxOw0KDQogICAgdyA9IGRpZ2l0c1t3XTsNCg0KICAgIC8vIElmIG5vbi16ZXJvLi4uDQogICAgaWYgKHcpIHsNCg0KICAgICAgLy8gU3VidHJhY3QgdGhlIG51bWJlciBvZiB0cmFpbGluZyB6ZXJvcyBvZiB0aGUgbGFzdCB3b3JkLg0KICAgICAgZm9yICg7IHcgJSAxMCA9PSAwOyB3IC89IDEwKSBsZW4tLTsNCg0KICAgICAgLy8gQWRkIHRoZSBudW1iZXIgb2YgZGlnaXRzIG9mIHRoZSBmaXJzdCB3b3JkLg0KICAgICAgZm9yICh3ID0gZGlnaXRzWzBdOyB3ID49IDEwOyB3IC89IDEwKSBsZW4rKzsNCiAgICB9DQoNCiAgICByZXR1cm4gbGVuOw0KICB9DQoNCg0KICBmdW5jdGlvbiBnZXRaZXJvU3RyaW5nKGspIHsNCiAgICB2YXIgenMgPSAnJzsNCiAgICBmb3IgKDsgay0tOykgenMgKz0gJzAnOw0KICAgIHJldHVybiB6czsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHZhbHVlIG9mIERlY2ltYWwgYHhgIHRvIHRoZSBwb3dlciBgbmAsIHdoZXJlIGBuYCBpcyBhbg0KICAgKiBpbnRlZ2VyIG9mIHR5cGUgbnVtYmVyLg0KICAgKg0KICAgKiBJbXBsZW1lbnRzICdleHBvbmVudGlhdGlvbiBieSBzcXVhcmluZycuIENhbGxlZCBieSBgcG93YCBhbmQgYHBhcnNlT3RoZXJgLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gaW50UG93KEN0b3IsIHgsIG4sIHByKSB7DQogICAgdmFyIGlzVHJ1bmNhdGVkLA0KICAgICAgciA9IG5ldyBDdG9yKDEpLA0KDQogICAgICAvLyBNYXggbiBvZiA5MDA3MTk5MjU0NzQwOTkxIHRha2VzIDUzIGxvb3AgaXRlcmF0aW9ucy4NCiAgICAgIC8vIE1heGltdW0gZGlnaXRzIGFycmF5IGxlbmd0aDsgbGVhdmVzIFsyOCwgMzRdIGd1YXJkIGRpZ2l0cy4NCiAgICAgIGsgPSBNYXRoLmNlaWwocHIgLyBMT0dfQkFTRSArIDQpOw0KDQogICAgZXh0ZXJuYWwgPSBmYWxzZTsNCg0KICAgIGZvciAoOzspIHsNCiAgICAgIGlmIChuICUgMikgew0KICAgICAgICByID0gci50aW1lcyh4KTsNCiAgICAgICAgaWYgKHRydW5jYXRlKHIuZCwgaykpIGlzVHJ1bmNhdGVkID0gdHJ1ZTsNCiAgICAgIH0NCg0KICAgICAgbiA9IG1hdGhmbG9vcihuIC8gMik7DQogICAgICBpZiAobiA9PT0gMCkgew0KDQogICAgICAgIC8vIFRvIGVuc3VyZSBjb3JyZWN0IHJvdW5kaW5nIHdoZW4gci5kIGlzIHRydW5jYXRlZCwgaW5jcmVtZW50IHRoZSBsYXN0IHdvcmQgaWYgaXQgaXMgemVyby4NCiAgICAgICAgbiA9IHIuZC5sZW5ndGggLSAxOw0KICAgICAgICBpZiAoaXNUcnVuY2F0ZWQgJiYgci5kW25dID09PSAwKSArK3IuZFtuXTsNCiAgICAgICAgYnJlYWs7DQogICAgICB9DQoNCiAgICAgIHggPSB4LnRpbWVzKHgpOw0KICAgICAgdHJ1bmNhdGUoeC5kLCBrKTsNCiAgICB9DQoNCiAgICBleHRlcm5hbCA9IHRydWU7DQoNCiAgICByZXR1cm4gcjsNCiAgfQ0KDQoNCiAgZnVuY3Rpb24gaXNPZGQobikgew0KICAgIHJldHVybiBuLmRbbi5kLmxlbmd0aCAtIDFdICYgMTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogSGFuZGxlIGBtYXhgIChgbmAgaXMgLTEpIGFuZCBgbWluYCAoYG5gIGlzIDEpLg0KICAgKi8NCiAgZnVuY3Rpb24gbWF4T3JNaW4oQ3RvciwgYXJncywgbikgew0KICAgIHZhciBrLCB5LA0KICAgICAgeCA9IG5ldyBDdG9yKGFyZ3NbMF0pLA0KICAgICAgaSA9IDA7DQoNCiAgICBmb3IgKDsgKytpIDwgYXJncy5sZW5ndGg7KSB7DQogICAgICB5ID0gbmV3IEN0b3IoYXJnc1tpXSk7DQoNCiAgICAgIC8vIE5hTj8NCiAgICAgIGlmICgheS5zKSB7DQogICAgICAgIHggPSB5Ow0KICAgICAgICBicmVhazsNCiAgICAgIH0NCg0KICAgICAgayA9IHguY21wKHkpOw0KDQogICAgICBpZiAoayA9PT0gbiB8fCBrID09PSAwICYmIHgucyA9PT0gbikgew0KICAgICAgICB4ID0geTsNCiAgICAgIH0NCiAgICB9DQoNCiAgICByZXR1cm4geDsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG5hdHVyYWwgZXhwb25lbnRpYWwgb2YgYHhgIHJvdW5kZWQgdG8gYHNkYCBzaWduaWZpY2FudA0KICAgKiBkaWdpdHMuDQogICAqDQogICAqIFRheWxvci9NYWNsYXVyaW4gc2VyaWVzLg0KICAgKg0KICAgKiBleHAoeCkgPSB4XjAvMCEgKyB4XjEvMSEgKyB4XjIvMiEgKyB4XjMvMyEgKyAuLi4NCiAgICoNCiAgICogQXJndW1lbnQgcmVkdWN0aW9uOg0KICAgKiAgIFJlcGVhdCB4ID0geCAvIDMyLCBrICs9IDUsIHVudGlsIHx4fCA8IDAuMQ0KICAgKiAgIGV4cCh4KSA9IGV4cCh4IC8gMl5rKV4oMl5rKQ0KICAgKg0KICAgKiBQcmV2aW91c2x5LCB0aGUgYXJndW1lbnQgd2FzIGluaXRpYWxseSByZWR1Y2VkIGJ5DQogICAqIGV4cCh4KSA9IGV4cChyKSAqIDEwXmsgIHdoZXJlIHIgPSB4IC0gayAqIGxuMTAsIGsgPSBmbG9vcih4IC8gbG4xMCkNCiAgICogdG8gZmlyc3QgcHV0IHIgaW4gdGhlIHJhbmdlIFswLCBsbjEwXSwgYmVmb3JlIGRpdmlkaW5nIGJ5IDMyIHVudGlsIHx4fCA8IDAuMSwgYnV0IHRoaXMgd2FzDQogICAqIGZvdW5kIHRvIGJlIHNsb3dlciB0aGFuIGp1c3QgZGl2aWRpbmcgcmVwZWF0ZWRseSBieSAzMiBhcyBhYm92ZS4NCiAgICoNCiAgICogTWF4IGludGVnZXIgYXJndW1lbnQ6IGV4cCgnMjA3MjMyNjU4MzY5NDY0MTMnKSA9IDYuM2UrOTAwMDAwMDAwMDAwMDAwMA0KICAgKiBNaW4gaW50ZWdlciBhcmd1bWVudDogZXhwKCctMjA3MjMyNjU4MzY5NDY0MTEnKSA9IDEuMmUtOTAwMDAwMDAwMDAwMDAwMA0KICAgKiAoTWF0aCBvYmplY3QgaW50ZWdlciBtaW4vbWF4OiBNYXRoLmV4cCg3MDkpID0gOC4yZSszMDcsIE1hdGguZXhwKC03NDUpID0gNWUtMzI0KQ0KICAgKg0KICAgKiAgZXhwKEluZmluaXR5KSAgPSBJbmZpbml0eQ0KICAgKiAgZXhwKC1JbmZpbml0eSkgPSAwDQogICAqICBleHAoTmFOKSAgICAgICA9IE5hTg0KICAgKiAgZXhwKMKxMCkgICAgICAgID0gMQ0KICAgKg0KICAgKiAgZXhwKHgpIGlzIG5vbi10ZXJtaW5hdGluZyBmb3IgYW55IGZpbml0ZSwgbm9uLXplcm8geC4NCiAgICoNCiAgICogIFRoZSByZXN1bHQgd2lsbCBhbHdheXMgYmUgY29ycmVjdGx5IHJvdW5kZWQuDQogICAqDQogICAqLw0KICBmdW5jdGlvbiBuYXR1cmFsRXhwb25lbnRpYWwoeCwgc2QpIHsNCiAgICB2YXIgZGVub21pbmF0b3IsIGd1YXJkLCBqLCBwb3csIHN1bSwgdCwgd3ByLA0KICAgICAgcmVwID0gMCwNCiAgICAgIGkgPSAwLA0KICAgICAgayA9IDAsDQogICAgICBDdG9yID0geC5jb25zdHJ1Y3RvciwNCiAgICAgIHJtID0gQ3Rvci5yb3VuZGluZywNCiAgICAgIHByID0gQ3Rvci5wcmVjaXNpb247DQoNCiAgICAvLyAwL05hTi9JbmZpbml0eT8NCiAgICBpZiAoIXguZCB8fCAheC5kWzBdIHx8IHguZSA+IDE3KSB7DQoNCiAgICAgIHJldHVybiBuZXcgQ3Rvcih4LmQNCiAgICAgICAgPyAheC5kWzBdID8gMSA6IHgucyA8IDAgPyAwIDogMSAvIDANCiAgICAgICAgOiB4LnMgPyB4LnMgPCAwID8gMCA6IHggOiAwIC8gMCk7DQogICAgfQ0KDQogICAgaWYgKHNkID09IG51bGwpIHsNCiAgICAgIGV4dGVybmFsID0gZmFsc2U7DQogICAgICB3cHIgPSBwcjsNCiAgICB9IGVsc2Ugew0KICAgICAgd3ByID0gc2Q7DQogICAgfQ0KDQogICAgdCA9IG5ldyBDdG9yKDAuMDMxMjUpOw0KDQogICAgLy8gd2hpbGUgYWJzKHgpID49IDAuMQ0KICAgIHdoaWxlICh4LmUgPiAtMikgew0KDQogICAgICAvLyB4ID0geCAvIDJeNQ0KICAgICAgeCA9IHgudGltZXModCk7DQogICAgICBrICs9IDU7DQogICAgfQ0KDQogICAgLy8gVXNlIDIgKiBsb2cxMCgyXmspICsgNSAoZW1waXJpY2FsbHkgZGVyaXZlZCkgdG8gZXN0aW1hdGUgdGhlIGluY3JlYXNlIGluIHByZWNpc2lvbg0KICAgIC8vIG5lY2Vzc2FyeSB0byBlbnN1cmUgdGhlIGZpcnN0IDQgcm91bmRpbmcgZGlnaXRzIGFyZSBjb3JyZWN0Lg0KICAgIGd1YXJkID0gTWF0aC5sb2cobWF0aHBvdygyLCBrKSkgLyBNYXRoLkxOMTAgKiAyICsgNSB8IDA7DQogICAgd3ByICs9IGd1YXJkOw0KICAgIGRlbm9taW5hdG9yID0gcG93ID0gc3VtID0gbmV3IEN0b3IoMSk7DQogICAgQ3Rvci5wcmVjaXNpb24gPSB3cHI7DQoNCiAgICBmb3IgKDs7KSB7DQogICAgICBwb3cgPSBmaW5hbGlzZShwb3cudGltZXMoeCksIHdwciwgMSk7DQogICAgICBkZW5vbWluYXRvciA9IGRlbm9taW5hdG9yLnRpbWVzKCsraSk7DQogICAgICB0ID0gc3VtLnBsdXMoZGl2aWRlKHBvdywgZGVub21pbmF0b3IsIHdwciwgMSkpOw0KDQogICAgICBpZiAoZGlnaXRzVG9TdHJpbmcodC5kKS5zbGljZSgwLCB3cHIpID09PSBkaWdpdHNUb1N0cmluZyhzdW0uZCkuc2xpY2UoMCwgd3ByKSkgew0KICAgICAgICBqID0gazsNCiAgICAgICAgd2hpbGUgKGotLSkgc3VtID0gZmluYWxpc2Uoc3VtLnRpbWVzKHN1bSksIHdwciwgMSk7DQoNCiAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBmaXJzdCA0IHJvdW5kaW5nIGRpZ2l0cyBhcmUgWzQ5XTk5OS4NCiAgICAgICAgLy8gSWYgc28sIHJlcGVhdCB0aGUgc3VtbWF0aW9uIHdpdGggYSBoaWdoZXIgcHJlY2lzaW9uLCBvdGhlcndpc2UNCiAgICAgICAgLy8gZS5nLiB3aXRoIHByZWNpc2lvbjogMTgsIHJvdW5kaW5nOiAxDQogICAgICAgIC8vIGV4cCgxOC40MDQyNzI0NjI1OTUwMzQwODM1Njc3OTM5MTk4NDM3NjEpID0gOTgzNzI1NjAuMTIyOTk5OTk5OSAoc2hvdWxkIGJlIDk4MzcyNTYwLjEyMykNCiAgICAgICAgLy8gYHdwciAtIGd1YXJkYCBpcyB0aGUgaW5kZXggb2YgZmlyc3Qgcm91bmRpbmcgZGlnaXQuDQogICAgICAgIGlmIChzZCA9PSBudWxsKSB7DQoNCiAgICAgICAgICBpZiAocmVwIDwgMyAmJiBjaGVja1JvdW5kaW5nRGlnaXRzKHN1bS5kLCB3cHIgLSBndWFyZCwgcm0sIHJlcCkpIHsNCiAgICAgICAgICAgIEN0b3IucHJlY2lzaW9uID0gd3ByICs9IDEwOw0KICAgICAgICAgICAgZGVub21pbmF0b3IgPSBwb3cgPSB0ID0gbmV3IEN0b3IoMSk7DQogICAgICAgICAgICBpID0gMDsNCiAgICAgICAgICAgIHJlcCsrOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICByZXR1cm4gZmluYWxpc2Uoc3VtLCBDdG9yLnByZWNpc2lvbiA9IHByLCBybSwgZXh0ZXJuYWwgPSB0cnVlKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgQ3Rvci5wcmVjaXNpb24gPSBwcjsNCiAgICAgICAgICByZXR1cm4gc3VtOw0KICAgICAgICB9DQogICAgICB9DQoNCiAgICAgIHN1bSA9IHQ7DQogICAgfQ0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgYHhgIHJvdW5kZWQgdG8gYHNkYCBzaWduaWZpY2FudA0KICAgKiBkaWdpdHMuDQogICAqDQogICAqICBsbigtbikgICAgICAgID0gTmFODQogICAqICBsbigwKSAgICAgICAgID0gLUluZmluaXR5DQogICAqICBsbigtMCkgICAgICAgID0gLUluZmluaXR5DQogICAqICBsbigxKSAgICAgICAgID0gMA0KICAgKiAgbG4oSW5maW5pdHkpICA9IEluZmluaXR5DQogICAqICBsbigtSW5maW5pdHkpID0gTmFODQogICAqICBsbihOYU4pICAgICAgID0gTmFODQogICAqDQogICAqICBsbihuKSAobiAhPSAxKSBpcyBub24tdGVybWluYXRpbmcuDQogICAqDQogICAqLw0KICBmdW5jdGlvbiBuYXR1cmFsTG9nYXJpdGhtKHksIHNkKSB7DQogICAgdmFyIGMsIGMwLCBkZW5vbWluYXRvciwgZSwgbnVtZXJhdG9yLCByZXAsIHN1bSwgdCwgd3ByLCB4MSwgeDIsDQogICAgICBuID0gMSwNCiAgICAgIGd1YXJkID0gMTAsDQogICAgICB4ID0geSwNCiAgICAgIHhkID0geC5kLA0KICAgICAgQ3RvciA9IHguY29uc3RydWN0b3IsDQogICAgICBybSA9IEN0b3Iucm91bmRpbmcsDQogICAgICBwciA9IEN0b3IucHJlY2lzaW9uOw0KDQogICAgLy8gSXMgeCBuZWdhdGl2ZSBvciBJbmZpbml0eSwgTmFOLCAwIG9yIDE/DQogICAgaWYgKHgucyA8IDAgfHwgIXhkIHx8ICF4ZFswXSB8fCAheC5lICYmIHhkWzBdID09IDEgJiYgeGQubGVuZ3RoID09IDEpIHsNCiAgICAgIHJldHVybiBuZXcgQ3Rvcih4ZCAmJiAheGRbMF0gPyAtMSAvIDAgOiB4LnMgIT0gMSA/IE5hTiA6IHhkID8gMCA6IHgpOw0KICAgIH0NCg0KICAgIGlmIChzZCA9PSBudWxsKSB7DQogICAgICBleHRlcm5hbCA9IGZhbHNlOw0KICAgICAgd3ByID0gcHI7DQogICAgfSBlbHNlIHsNCiAgICAgIHdwciA9IHNkOw0KICAgIH0NCg0KICAgIEN0b3IucHJlY2lzaW9uID0gd3ByICs9IGd1YXJkOw0KICAgIGMgPSBkaWdpdHNUb1N0cmluZyh4ZCk7DQogICAgYzAgPSBjLmNoYXJBdCgwKTsNCg0KICAgIGlmIChNYXRoLmFicyhlID0geC5lKSA8IDEuNWUxNSkgew0KDQogICAgICAvLyBBcmd1bWVudCByZWR1Y3Rpb24uDQogICAgICAvLyBUaGUgc2VyaWVzIGNvbnZlcmdlcyBmYXN0ZXIgdGhlIGNsb3NlciB0aGUgYXJndW1lbnQgaXMgdG8gMSwgc28gdXNpbmcNCiAgICAgIC8vIGxuKGFeYikgPSBiICogbG4oYSksICAgbG4oYSkgPSBsbihhXmIpIC8gYg0KICAgICAgLy8gbXVsdGlwbHkgdGhlIGFyZ3VtZW50IGJ5IGl0c2VsZiB1bnRpbCB0aGUgbGVhZGluZyBkaWdpdHMgb2YgdGhlIHNpZ25pZmljYW5kIGFyZSA3LCA4LCA5LA0KICAgICAgLy8gMTAsIDExLCAxMiBvciAxMywgcmVjb3JkaW5nIHRoZSBudW1iZXIgb2YgbXVsdGlwbGljYXRpb25zIHNvIHRoZSBzdW0gb2YgdGhlIHNlcmllcyBjYW4NCiAgICAgIC8vIGxhdGVyIGJlIGRpdmlkZWQgYnkgdGhpcyBudW1iZXIsIHRoZW4gc2VwYXJhdGUgb3V0IHRoZSBwb3dlciBvZiAxMCB1c2luZw0KICAgICAgLy8gbG4oYSoxMF5iKSA9IGxuKGEpICsgYipsbigxMCkuDQoNCiAgICAgIC8vIG1heCBuIGlzIDIxIChnaXZlcyAwLjksIDEuMCBvciAxLjEpICg5ZTE1IC8gMjEgPSA0LjJlMTQpLg0KICAgICAgLy93aGlsZSAoYzAgPCA5ICYmIGMwICE9IDEgfHwgYzAgPT0gMSAmJiBjLmNoYXJBdCgxKSA+IDEpIHsNCiAgICAgIC8vIG1heCBuIGlzIDYgKGdpdmVzIDAuNyAtIDEuMykNCiAgICAgIHdoaWxlIChjMCA8IDcgJiYgYzAgIT0gMSB8fCBjMCA9PSAxICYmIGMuY2hhckF0KDEpID4gMykgew0KICAgICAgICB4ID0geC50aW1lcyh5KTsNCiAgICAgICAgYyA9IGRpZ2l0c1RvU3RyaW5nKHguZCk7DQogICAgICAgIGMwID0gYy5jaGFyQXQoMCk7DQogICAgICAgIG4rKzsNCiAgICAgIH0NCg0KICAgICAgZSA9IHguZTsNCg0KICAgICAgaWYgKGMwID4gMSkgew0KICAgICAgICB4ID0gbmV3IEN0b3IoJzAuJyArIGMpOw0KICAgICAgICBlKys7DQogICAgICB9IGVsc2Ugew0KICAgICAgICB4ID0gbmV3IEN0b3IoYzAgKyAnLicgKyBjLnNsaWNlKDEpKTsNCiAgICAgIH0NCiAgICB9IGVsc2Ugew0KDQogICAgICAvLyBUaGUgYXJndW1lbnQgcmVkdWN0aW9uIG1ldGhvZCBhYm92ZSBtYXkgcmVzdWx0IGluIG92ZXJmbG93IGlmIHRoZSBhcmd1bWVudCB5IGlzIGEgbWFzc2l2ZQ0KICAgICAgLy8gbnVtYmVyIHdpdGggZXhwb25lbnQgPj0gMTUwMDAwMDAwMDAwMDAwMCAoOWUxNSAvIDYgPSAxLjVlMTUpLCBzbyBpbnN0ZWFkIHJlY2FsbCB0aGlzDQogICAgICAvLyBmdW5jdGlvbiB1c2luZyBsbih4KjEwXmUpID0gbG4oeCkgKyBlKmxuKDEwKS4NCiAgICAgIHQgPSBnZXRMbjEwKEN0b3IsIHdwciArIDIsIHByKS50aW1lcyhlICsgJycpOw0KICAgICAgeCA9IG5hdHVyYWxMb2dhcml0aG0obmV3IEN0b3IoYzAgKyAnLicgKyBjLnNsaWNlKDEpKSwgd3ByIC0gZ3VhcmQpLnBsdXModCk7DQogICAgICBDdG9yLnByZWNpc2lvbiA9IHByOw0KDQogICAgICByZXR1cm4gc2QgPT0gbnVsbCA/IGZpbmFsaXNlKHgsIHByLCBybSwgZXh0ZXJuYWwgPSB0cnVlKSA6IHg7DQogICAgfQ0KDQogICAgLy8geDEgaXMgeCByZWR1Y2VkIHRvIGEgdmFsdWUgbmVhciAxLg0KICAgIHgxID0geDsNCg0KICAgIC8vIFRheWxvciBzZXJpZXMuDQogICAgLy8gbG4oeSkgPSBsbigoMSArIHgpLygxIC0geCkpID0gMih4ICsgeF4zLzMgKyB4XjUvNSArIHheNy83ICsgLi4uKQ0KICAgIC8vIHdoZXJlIHggPSAoeSAtIDEpLyh5ICsgMSkgICAgKHx4fCA8IDEpDQogICAgc3VtID0gbnVtZXJhdG9yID0geCA9IGRpdmlkZSh4Lm1pbnVzKDEpLCB4LnBsdXMoMSksIHdwciwgMSk7DQogICAgeDIgPSBmaW5hbGlzZSh4LnRpbWVzKHgpLCB3cHIsIDEpOw0KICAgIGRlbm9taW5hdG9yID0gMzsNCg0KICAgIGZvciAoOzspIHsNCiAgICAgIG51bWVyYXRvciA9IGZpbmFsaXNlKG51bWVyYXRvci50aW1lcyh4MiksIHdwciwgMSk7DQogICAgICB0ID0gc3VtLnBsdXMoZGl2aWRlKG51bWVyYXRvciwgbmV3IEN0b3IoZGVub21pbmF0b3IpLCB3cHIsIDEpKTsNCg0KICAgICAgaWYgKGRpZ2l0c1RvU3RyaW5nKHQuZCkuc2xpY2UoMCwgd3ByKSA9PT0gZGlnaXRzVG9TdHJpbmcoc3VtLmQpLnNsaWNlKDAsIHdwcikpIHsNCiAgICAgICAgc3VtID0gc3VtLnRpbWVzKDIpOw0KDQogICAgICAgIC8vIFJldmVyc2UgdGhlIGFyZ3VtZW50IHJlZHVjdGlvbi4gQ2hlY2sgdGhhdCBlIGlzIG5vdCAwIGJlY2F1c2UsIGJlc2lkZXMgcHJldmVudGluZyBhbg0KICAgICAgICAvLyB1bm5lY2Vzc2FyeSBjYWxjdWxhdGlvbiwgLTAgKyAwID0gKzAgYW5kIHRvIGVuc3VyZSBjb3JyZWN0IHJvdW5kaW5nIC0wIG5lZWRzIHRvIHN0YXkgLTAuDQogICAgICAgIGlmIChlICE9PSAwKSBzdW0gPSBzdW0ucGx1cyhnZXRMbjEwKEN0b3IsIHdwciArIDIsIHByKS50aW1lcyhlICsgJycpKTsNCiAgICAgICAgc3VtID0gZGl2aWRlKHN1bSwgbmV3IEN0b3IobiksIHdwciwgMSk7DQoNCiAgICAgICAgLy8gSXMgcm0gPiAzIGFuZCB0aGUgZmlyc3QgNCByb3VuZGluZyBkaWdpdHMgNDk5OSwgb3Igcm0gPCA0IChvciB0aGUgc3VtbWF0aW9uIGhhcw0KICAgICAgICAvLyBiZWVuIHJlcGVhdGVkIHByZXZpb3VzbHkpIGFuZCB0aGUgZmlyc3QgNCByb3VuZGluZyBkaWdpdHMgOTk5OT8NCiAgICAgICAgLy8gSWYgc28sIHJlc3RhcnQgdGhlIHN1bW1hdGlvbiB3aXRoIGEgaGlnaGVyIHByZWNpc2lvbiwgb3RoZXJ3aXNlDQogICAgICAgIC8vIGUuZy4gd2l0aCBwcmVjaXNpb246IDEyLCByb3VuZGluZzogMQ0KICAgICAgICAvLyBsbigxMzU1MjAwMjguNjEyNjA5MTcxNDI2NTM4MTUzMykgPSAxOC43MjQ2Mjk5OTk5IHdoZW4gaXQgc2hvdWxkIGJlIDE4LjcyNDYzLg0KICAgICAgICAvLyBgd3ByIC0gZ3VhcmRgIGlzIHRoZSBpbmRleCBvZiBmaXJzdCByb3VuZGluZyBkaWdpdC4NCiAgICAgICAgaWYgKHNkID09IG51bGwpIHsNCiAgICAgICAgICBpZiAoY2hlY2tSb3VuZGluZ0RpZ2l0cyhzdW0uZCwgd3ByIC0gZ3VhcmQsIHJtLCByZXApKSB7DQogICAgICAgICAgICBDdG9yLnByZWNpc2lvbiA9IHdwciArPSBndWFyZDsNCiAgICAgICAgICAgIHQgPSBudW1lcmF0b3IgPSB4ID0gZGl2aWRlKHgxLm1pbnVzKDEpLCB4MS5wbHVzKDEpLCB3cHIsIDEpOw0KICAgICAgICAgICAgeDIgPSBmaW5hbGlzZSh4LnRpbWVzKHgpLCB3cHIsIDEpOw0KICAgICAgICAgICAgZGVub21pbmF0b3IgPSByZXAgPSAxOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICByZXR1cm4gZmluYWxpc2Uoc3VtLCBDdG9yLnByZWNpc2lvbiA9IHByLCBybSwgZXh0ZXJuYWwgPSB0cnVlKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgQ3Rvci5wcmVjaXNpb24gPSBwcjsNCiAgICAgICAgICByZXR1cm4gc3VtOw0KICAgICAgICB9DQogICAgICB9DQoNCiAgICAgIHN1bSA9IHQ7DQogICAgICBkZW5vbWluYXRvciArPSAyOw0KICAgIH0NCiAgfQ0KDQoNCiAgLy8gwrFJbmZpbml0eSwgTmFOLg0KICBmdW5jdGlvbiBub25GaW5pdGVUb1N0cmluZyh4KSB7DQogICAgLy8gVW5zaWduZWQuDQogICAgcmV0dXJuIFN0cmluZyh4LnMgKiB4LnMgLyAwKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUGFyc2UgdGhlIHZhbHVlIG9mIGEgbmV3IERlY2ltYWwgYHhgIGZyb20gc3RyaW5nIGBzdHJgLg0KICAgKi8NCiAgZnVuY3Rpb24gcGFyc2VEZWNpbWFsKHgsIHN0cikgew0KICAgIHZhciBlLCBpLCBsZW47DQoNCiAgICAvLyBUT0RPIEJpZ0ludCBzdHI6IG5vIG5lZWQgdG8gY2hlY2sgZm9yIGRlY2ltYWwgcG9pbnQsIGV4cG9uZW50aWFsIGZvcm0gb3IgbGVhZGluZyB6ZXJvcy4NCiAgICAvLyBEZWNpbWFsIHBvaW50Pw0KICAgIGlmICgoZSA9IHN0ci5pbmRleE9mKCcuJykpID4gLTEpIHN0ciA9IHN0ci5yZXBsYWNlKCcuJywgJycpOw0KDQogICAgLy8gRXhwb25lbnRpYWwgZm9ybT8NCiAgICBpZiAoKGkgPSBzdHIuc2VhcmNoKC9lL2kpKSA+IDApIHsNCg0KICAgICAgLy8gRGV0ZXJtaW5lIGV4cG9uZW50Lg0KICAgICAgaWYgKGUgPCAwKSBlID0gaTsNCiAgICAgIGUgKz0gK3N0ci5zbGljZShpICsgMSk7DQogICAgICBzdHIgPSBzdHIuc3Vic3RyaW5nKDAsIGkpOw0KICAgIH0gZWxzZSBpZiAoZSA8IDApIHsNCg0KICAgICAgLy8gSW50ZWdlci4NCiAgICAgIGUgPSBzdHIubGVuZ3RoOw0KICAgIH0NCg0KICAgIC8vIERldGVybWluZSBsZWFkaW5nIHplcm9zLg0KICAgIGZvciAoaSA9IDA7IHN0ci5jaGFyQ29kZUF0KGkpID09PSA0ODsgaSsrKTsNCg0KICAgIC8vIERldGVybWluZSB0cmFpbGluZyB6ZXJvcy4NCiAgICBmb3IgKGxlbiA9IHN0ci5sZW5ndGg7IHN0ci5jaGFyQ29kZUF0KGxlbiAtIDEpID09PSA0ODsgLS1sZW4pOw0KICAgIHN0ciA9IHN0ci5zbGljZShpLCBsZW4pOw0KDQogICAgaWYgKHN0cikgew0KICAgICAgbGVuIC09IGk7DQogICAgICB4LmUgPSBlID0gZSAtIGkgLSAxOw0KICAgICAgeC5kID0gW107DQoNCiAgICAgIC8vIFRyYW5zZm9ybSBiYXNlDQoNCiAgICAgIC8vIGUgaXMgdGhlIGJhc2UgMTAgZXhwb25lbnQuDQogICAgICAvLyBpIGlzIHdoZXJlIHRvIHNsaWNlIHN0ciB0byBnZXQgdGhlIGZpcnN0IHdvcmQgb2YgdGhlIGRpZ2l0cyBhcnJheS4NCiAgICAgIGkgPSAoZSArIDEpICUgTE9HX0JBU0U7DQogICAgICBpZiAoZSA8IDApIGkgKz0gTE9HX0JBU0U7DQoNCiAgICAgIGlmIChpIDwgbGVuKSB7DQogICAgICAgIGlmIChpKSB4LmQucHVzaCgrc3RyLnNsaWNlKDAsIGkpKTsNCiAgICAgICAgZm9yIChsZW4gLT0gTE9HX0JBU0U7IGkgPCBsZW47KSB4LmQucHVzaCgrc3RyLnNsaWNlKGksIGkgKz0gTE9HX0JBU0UpKTsNCiAgICAgICAgc3RyID0gc3RyLnNsaWNlKGkpOw0KICAgICAgICBpID0gTE9HX0JBU0UgLSBzdHIubGVuZ3RoOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaSAtPSBsZW47DQogICAgICB9DQoNCiAgICAgIGZvciAoOyBpLS07KSBzdHIgKz0gJzAnOw0KICAgICAgeC5kLnB1c2goK3N0cik7DQoNCiAgICAgIGlmIChleHRlcm5hbCkgew0KDQogICAgICAgIC8vIE92ZXJmbG93Pw0KICAgICAgICBpZiAoeC5lID4geC5jb25zdHJ1Y3Rvci5tYXhFKSB7DQoNCiAgICAgICAgICAvLyBJbmZpbml0eS4NCiAgICAgICAgICB4LmQgPSBudWxsOw0KICAgICAgICAgIHguZSA9IE5hTjsNCg0KICAgICAgICAvLyBVbmRlcmZsb3c/DQogICAgICAgIH0gZWxzZSBpZiAoeC5lIDwgeC5jb25zdHJ1Y3Rvci5taW5FKSB7DQoNCiAgICAgICAgICAvLyBaZXJvLg0KICAgICAgICAgIHguZSA9IDA7DQogICAgICAgICAgeC5kID0gWzBdOw0KICAgICAgICAgIC8vIHguY29uc3RydWN0b3IudW5kZXJmbG93ID0gdHJ1ZTsNCiAgICAgICAgfSAvLyBlbHNlIHguY29uc3RydWN0b3IudW5kZXJmbG93ID0gZmFsc2U7DQogICAgICB9DQogICAgfSBlbHNlIHsNCg0KICAgICAgLy8gWmVyby4NCiAgICAgIHguZSA9IDA7DQogICAgICB4LmQgPSBbMF07DQogICAgfQ0KDQogICAgcmV0dXJuIHg7DQogIH0NCg0KDQogIC8qDQogICAqIFBhcnNlIHRoZSB2YWx1ZSBvZiBhIG5ldyBEZWNpbWFsIGB4YCBmcm9tIGEgc3RyaW5nIGBzdHJgLCB3aGljaCBpcyBub3QgYSBkZWNpbWFsIHZhbHVlLg0KICAgKi8NCiAgZnVuY3Rpb24gcGFyc2VPdGhlcih4LCBzdHIpIHsNCiAgICB2YXIgYmFzZSwgQ3RvciwgZGl2aXNvciwgaSwgaXNGbG9hdCwgbGVuLCBwLCB4ZCwgeGU7DQoNCiAgICBpZiAoc3RyLmluZGV4T2YoJ18nKSA+IC0xKSB7DQogICAgICBzdHIgPSBzdHIucmVwbGFjZSgvKFxkKV8oPz1cZCkvZywgJyQxJyk7DQogICAgICBpZiAoaXNEZWNpbWFsLnRlc3Qoc3RyKSkgcmV0dXJuIHBhcnNlRGVjaW1hbCh4LCBzdHIpOw0KICAgIH0gZWxzZSBpZiAoc3RyID09PSAnSW5maW5pdHknIHx8IHN0ciA9PT0gJ05hTicpIHsNCiAgICAgIGlmICghK3N0cikgeC5zID0gTmFOOw0KICAgICAgeC5lID0gTmFOOw0KICAgICAgeC5kID0gbnVsbDsNCiAgICAgIHJldHVybiB4Ow0KICAgIH0NCg0KICAgIGlmIChpc0hleC50ZXN0KHN0cikpICB7DQogICAgICBiYXNlID0gMTY7DQogICAgICBzdHIgPSBzdHIudG9Mb3dlckNhc2UoKTsNCiAgICB9IGVsc2UgaWYgKGlzQmluYXJ5LnRlc3Qoc3RyKSkgIHsNCiAgICAgIGJhc2UgPSAyOw0KICAgIH0gZWxzZSBpZiAoaXNPY3RhbC50ZXN0KHN0cikpICB7DQogICAgICBiYXNlID0gODsNCiAgICB9IGVsc2Ugew0KICAgICAgdGhyb3cgRXJyb3IoaW52YWxpZEFyZ3VtZW50ICsgc3RyKTsNCiAgICB9DQoNCiAgICAvLyBJcyB0aGVyZSBhIGJpbmFyeSBleHBvbmVudCBwYXJ0Pw0KICAgIGkgPSBzdHIuc2VhcmNoKC9wL2kpOw0KDQogICAgaWYgKGkgPiAwKSB7DQogICAgICBwID0gK3N0ci5zbGljZShpICsgMSk7DQogICAgICBzdHIgPSBzdHIuc3Vic3RyaW5nKDIsIGkpOw0KICAgIH0gZWxzZSB7DQogICAgICBzdHIgPSBzdHIuc2xpY2UoMik7DQogICAgfQ0KDQogICAgLy8gQ29udmVydCBgc3RyYCBhcyBhbiBpbnRlZ2VyIHRoZW4gZGl2aWRlIHRoZSByZXN1bHQgYnkgYGJhc2VgIHJhaXNlZCB0byBhIHBvd2VyIHN1Y2ggdGhhdCB0aGUNCiAgICAvLyBmcmFjdGlvbiBwYXJ0IHdpbGwgYmUgcmVzdG9yZWQuDQogICAgaSA9IHN0ci5pbmRleE9mKCcuJyk7DQogICAgaXNGbG9hdCA9IGkgPj0gMDsNCiAgICBDdG9yID0geC5jb25zdHJ1Y3RvcjsNCg0KICAgIGlmIChpc0Zsb2F0KSB7DQogICAgICBzdHIgPSBzdHIucmVwbGFjZSgnLicsICcnKTsNCiAgICAgIGxlbiA9IHN0ci5sZW5ndGg7DQogICAgICBpID0gbGVuIC0gaTsNCg0KICAgICAgLy8gbG9nWzEwXSgxNikgPSAxLjIwNDEuLi4gLCBsb2dbMTBdKDg4KSA9IDEuOTQ0NC4uLi4NCiAgICAgIGRpdmlzb3IgPSBpbnRQb3coQ3RvciwgbmV3IEN0b3IoYmFzZSksIGksIGkgKiAyKTsNCiAgICB9DQoNCiAgICB4ZCA9IGNvbnZlcnRCYXNlKHN0ciwgYmFzZSwgQkFTRSk7DQogICAgeGUgPSB4ZC5sZW5ndGggLSAxOw0KDQogICAgLy8gUmVtb3ZlIHRyYWlsaW5nIHplcm9zLg0KICAgIGZvciAoaSA9IHhlOyB4ZFtpXSA9PT0gMDsgLS1pKSB4ZC5wb3AoKTsNCiAgICBpZiAoaSA8IDApIHJldHVybiBuZXcgQ3Rvcih4LnMgKiAwKTsNCiAgICB4LmUgPSBnZXRCYXNlMTBFeHBvbmVudCh4ZCwgeGUpOw0KICAgIHguZCA9IHhkOw0KICAgIGV4dGVybmFsID0gZmFsc2U7DQoNCiAgICAvLyBBdCB3aGF0IHByZWNpc2lvbiB0byBwZXJmb3JtIHRoZSBkaXZpc2lvbiB0byBlbnN1cmUgZXhhY3QgY29udmVyc2lvbj8NCiAgICAvLyBtYXhEZWNpbWFsSW50ZWdlclBhcnREaWdpdENvdW50ID0gY2VpbChsb2dbMTBdKGIpICogb3RoZXJCYXNlSW50ZWdlclBhcnREaWdpdENvdW50KQ0KICAgIC8vIGxvZ1sxMF0oMikgPSAwLjMwMTAzLCBsb2dbMTBdKDgpID0gMC45MDMwOSwgbG9nWzEwXSgxNikgPSAxLjIwNDEyDQogICAgLy8gRS5nLiBjZWlsKDEuMiAqIDMpID0gNCwgc28gdXAgdG8gNCBkZWNpbWFsIGRpZ2l0cyBhcmUgbmVlZGVkIHRvIHJlcHJlc2VudCAzIGhleCBpbnQgZGlnaXRzLg0KICAgIC8vIG1heERlY2ltYWxGcmFjdGlvblBhcnREaWdpdENvdW50ID0ge0hleDo0fE9jdDozfEJpbjoxfSAqIG90aGVyQmFzZUZyYWN0aW9uUGFydERpZ2l0Q291bnQNCiAgICAvLyBUaGVyZWZvcmUgdXNpbmcgNCAqIHRoZSBudW1iZXIgb2YgZGlnaXRzIG9mIHN0ciB3aWxsIGFsd2F5cyBiZSBlbm91Z2guDQogICAgaWYgKGlzRmxvYXQpIHggPSBkaXZpZGUoeCwgZGl2aXNvciwgbGVuICogNCk7DQoNCiAgICAvLyBNdWx0aXBseSBieSB0aGUgYmluYXJ5IGV4cG9uZW50IHBhcnQgaWYgcHJlc2VudC4NCiAgICBpZiAocCkgeCA9IHgudGltZXMoTWF0aC5hYnMocCkgPCA1NCA/IG1hdGhwb3coMiwgcCkgOiBEZWNpbWFsLnBvdygyLCBwKSk7DQogICAgZXh0ZXJuYWwgPSB0cnVlOw0KDQogICAgcmV0dXJuIHg7DQogIH0NCg0KDQogIC8qDQogICAqIHNpbih4KSA9IHggLSB4XjMvMyEgKyB4XjUvNSEgLSAuLi4NCiAgICogfHh8IDwgcGkvMg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gc2luZShDdG9yLCB4KSB7DQogICAgdmFyIGssDQogICAgICBsZW4gPSB4LmQubGVuZ3RoOw0KDQogICAgaWYgKGxlbiA8IDMpIHsNCiAgICAgIHJldHVybiB4LmlzWmVybygpID8geCA6IHRheWxvclNlcmllcyhDdG9yLCAyLCB4LCB4KTsNCiAgICB9DQoNCiAgICAvLyBBcmd1bWVudCByZWR1Y3Rpb246IHNpbig1eCkgPSAxNipzaW5eNSh4KSAtIDIwKnNpbl4zKHgpICsgNSpzaW4oeCkNCiAgICAvLyBpLmUuIHNpbih4KSA9IDE2KnNpbl41KHgvNSkgLSAyMCpzaW5eMyh4LzUpICsgNSpzaW4oeC81KQ0KICAgIC8vIGFuZCAgc2luKHgpID0gc2luKHgvNSkoNSArIHNpbl4yKHgvNSkoMTZzaW5eMih4LzUpIC0gMjApKQ0KDQogICAgLy8gRXN0aW1hdGUgdGhlIG9wdGltdW0gbnVtYmVyIG9mIHRpbWVzIHRvIHVzZSB0aGUgYXJndW1lbnQgcmVkdWN0aW9uLg0KICAgIGsgPSAxLjQgKiBNYXRoLnNxcnQobGVuKTsNCiAgICBrID0gayA+IDE2ID8gMTYgOiBrIHwgMDsNCg0KICAgIHggPSB4LnRpbWVzKDEgLyB0aW55UG93KDUsIGspKTsNCiAgICB4ID0gdGF5bG9yU2VyaWVzKEN0b3IsIDIsIHgsIHgpOw0KDQogICAgLy8gUmV2ZXJzZSBhcmd1bWVudCByZWR1Y3Rpb24NCiAgICB2YXIgc2luMl94LA0KICAgICAgZDUgPSBuZXcgQ3Rvcig1KSwNCiAgICAgIGQxNiA9IG5ldyBDdG9yKDE2KSwNCiAgICAgIGQyMCA9IG5ldyBDdG9yKDIwKTsNCiAgICBmb3IgKDsgay0tOykgew0KICAgICAgc2luMl94ID0geC50aW1lcyh4KTsNCiAgICAgIHggPSB4LnRpbWVzKGQ1LnBsdXMoc2luMl94LnRpbWVzKGQxNi50aW1lcyhzaW4yX3gpLm1pbnVzKGQyMCkpKSk7DQogICAgfQ0KDQogICAgcmV0dXJuIHg7DQogIH0NCg0KDQogIC8vIENhbGN1bGF0ZSBUYXlsb3Igc2VyaWVzIGZvciBgY29zYCwgYGNvc2hgLCBgc2luYCBhbmQgYHNpbmhgLg0KICBmdW5jdGlvbiB0YXlsb3JTZXJpZXMoQ3RvciwgbiwgeCwgeSwgaXNIeXBlcmJvbGljKSB7DQogICAgdmFyIGosIHQsIHUsIHgyLA0KICAgICAgcHIgPSBDdG9yLnByZWNpc2lvbiwNCiAgICAgIGsgPSBNYXRoLmNlaWwocHIgLyBMT0dfQkFTRSk7DQoNCiAgICBleHRlcm5hbCA9IGZhbHNlOw0KICAgIHgyID0geC50aW1lcyh4KTsNCiAgICB1ID0gbmV3IEN0b3IoeSk7DQoNCiAgICBmb3IgKDs7KSB7DQogICAgICB0ID0gZGl2aWRlKHUudGltZXMoeDIpLCBuZXcgQ3RvcihuKysgKiBuKyspLCBwciwgMSk7DQogICAgICB1ID0gaXNIeXBlcmJvbGljID8geS5wbHVzKHQpIDogeS5taW51cyh0KTsNCiAgICAgIHkgPSBkaXZpZGUodC50aW1lcyh4MiksIG5ldyBDdG9yKG4rKyAqIG4rKyksIHByLCAxKTsNCiAgICAgIHQgPSB1LnBsdXMoeSk7DQoNCiAgICAgIGlmICh0LmRba10gIT09IHZvaWQgMCkgew0KICAgICAgICBmb3IgKGogPSBrOyB0LmRbal0gPT09IHUuZFtqXSAmJiBqLS07KTsNCiAgICAgICAgaWYgKGogPT0gLTEpIGJyZWFrOw0KICAgICAgfQ0KDQogICAgICBqID0gdTsNCiAgICAgIHUgPSB5Ow0KICAgICAgeSA9IHQ7DQogICAgICB0ID0gajsNCiAgICB9DQoNCiAgICBleHRlcm5hbCA9IHRydWU7DQogICAgdC5kLmxlbmd0aCA9IGsgKyAxOw0KDQogICAgcmV0dXJuIHQ7DQogIH0NCg0KDQogIC8vIEV4cG9uZW50IGUgbXVzdCBiZSBwb3NpdGl2ZSBhbmQgbm9uLXplcm8uDQogIGZ1bmN0aW9uIHRpbnlQb3coYiwgZSkgew0KICAgIHZhciBuID0gYjsNCiAgICB3aGlsZSAoLS1lKSBuICo9IGI7DQogICAgcmV0dXJuIG47DQogIH0NCg0KDQogIC8vIFJldHVybiB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgYHhgIHJlZHVjZWQgdG8gbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGhhbGYgcGkuDQogIGZ1bmN0aW9uIHRvTGVzc1RoYW5IYWxmUGkoQ3RvciwgeCkgew0KICAgIHZhciB0LA0KICAgICAgaXNOZWcgPSB4LnMgPCAwLA0KICAgICAgcGkgPSBnZXRQaShDdG9yLCBDdG9yLnByZWNpc2lvbiwgMSksDQogICAgICBoYWxmUGkgPSBwaS50aW1lcygwLjUpOw0KDQogICAgeCA9IHguYWJzKCk7DQoNCiAgICBpZiAoeC5sdGUoaGFsZlBpKSkgew0KICAgICAgcXVhZHJhbnQgPSBpc05lZyA/IDQgOiAxOw0KICAgICAgcmV0dXJuIHg7DQogICAgfQ0KDQogICAgdCA9IHguZGl2VG9JbnQocGkpOw0KDQogICAgaWYgKHQuaXNaZXJvKCkpIHsNCiAgICAgIHF1YWRyYW50ID0gaXNOZWcgPyAzIDogMjsNCiAgICB9IGVsc2Ugew0KICAgICAgeCA9IHgubWludXModC50aW1lcyhwaSkpOw0KDQogICAgICAvLyAwIDw9IHggPCBwaQ0KICAgICAgaWYgKHgubHRlKGhhbGZQaSkpIHsNCiAgICAgICAgcXVhZHJhbnQgPSBpc09kZCh0KSA/IChpc05lZyA/IDIgOiAzKSA6IChpc05lZyA/IDQgOiAxKTsNCiAgICAgICAgcmV0dXJuIHg7DQogICAgICB9DQoNCiAgICAgIHF1YWRyYW50ID0gaXNPZGQodCkgPyAoaXNOZWcgPyAxIDogNCkgOiAoaXNOZWcgPyAzIDogMik7DQogICAgfQ0KDQogICAgcmV0dXJuIHgubWludXMocGkpLmFicygpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIERlY2ltYWwgYHhgIGFzIGEgc3RyaW5nIGluIGJhc2UgYGJhc2VPdXRgLg0KICAgKg0KICAgKiBJZiB0aGUgb3B0aW9uYWwgYHNkYCBhcmd1bWVudCBpcyBwcmVzZW50IGluY2x1ZGUgYSBiaW5hcnkgZXhwb25lbnQgc3VmZml4Lg0KICAgKi8NCiAgZnVuY3Rpb24gdG9TdHJpbmdCaW5hcnkoeCwgYmFzZU91dCwgc2QsIHJtKSB7DQogICAgdmFyIGJhc2UsIGUsIGksIGssIGxlbiwgcm91bmRVcCwgc3RyLCB4ZCwgeSwNCiAgICAgIEN0b3IgPSB4LmNvbnN0cnVjdG9yLA0KICAgICAgaXNFeHAgPSBzZCAhPT0gdm9pZCAwOw0KDQogICAgaWYgKGlzRXhwKSB7DQogICAgICBjaGVja0ludDMyKHNkLCAxLCBNQVhfRElHSVRTKTsNCiAgICAgIGlmIChybSA9PT0gdm9pZCAwKSBybSA9IEN0b3Iucm91bmRpbmc7DQogICAgICBlbHNlIGNoZWNrSW50MzIocm0sIDAsIDgpOw0KICAgIH0gZWxzZSB7DQogICAgICBzZCA9IEN0b3IucHJlY2lzaW9uOw0KICAgICAgcm0gPSBDdG9yLnJvdW5kaW5nOw0KICAgIH0NCg0KICAgIGlmICgheC5pc0Zpbml0ZSgpKSB7DQogICAgICBzdHIgPSBub25GaW5pdGVUb1N0cmluZyh4KTsNCiAgICB9IGVsc2Ugew0KICAgICAgc3RyID0gZmluaXRlVG9TdHJpbmcoeCk7DQogICAgICBpID0gc3RyLmluZGV4T2YoJy4nKTsNCg0KICAgICAgLy8gVXNlIGV4cG9uZW50aWFsIG5vdGF0aW9uIGFjY29yZGluZyB0byBgdG9FeHBQb3NgIGFuZCBgdG9FeHBOZWdgPyBObywgYnV0IGlmIHJlcXVpcmVkOg0KICAgICAgLy8gbWF4QmluYXJ5RXhwb25lbnQgPSBmbG9vcigoZGVjaW1hbEV4cG9uZW50ICsgMSkgKiBsb2dbMl0oMTApKQ0KICAgICAgLy8gbWluQmluYXJ5RXhwb25lbnQgPSBmbG9vcihkZWNpbWFsRXhwb25lbnQgKiBsb2dbMl0oMTApKQ0KICAgICAgLy8gbG9nWzJdKDEwKSA9IDMuMzIxOTI4MDk0ODg3MzYyMzQ3ODcwMzE5NDI5NDg5MzkwMTc1ODY0DQoNCiAgICAgIGlmIChpc0V4cCkgew0KICAgICAgICBiYXNlID0gMjsNCiAgICAgICAgaWYgKGJhc2VPdXQgPT0gMTYpIHsNCiAgICAgICAgICBzZCA9IHNkICogNCAtIDM7DQogICAgICAgIH0gZWxzZSBpZiAoYmFzZU91dCA9PSA4KSB7DQogICAgICAgICAgc2QgPSBzZCAqIDMgLSAyOw0KICAgICAgICB9DQogICAgICB9IGVsc2Ugew0KICAgICAgICBiYXNlID0gYmFzZU91dDsNCiAgICAgIH0NCg0KICAgICAgLy8gQ29udmVydCB0aGUgbnVtYmVyIGFzIGFuIGludGVnZXIgdGhlbiBkaXZpZGUgdGhlIHJlc3VsdCBieSBpdHMgYmFzZSByYWlzZWQgdG8gYSBwb3dlciBzdWNoDQogICAgICAvLyB0aGF0IHRoZSBmcmFjdGlvbiBwYXJ0IHdpbGwgYmUgcmVzdG9yZWQuDQoNCiAgICAgIC8vIE5vbi1pbnRlZ2VyLg0KICAgICAgaWYgKGkgPj0gMCkgew0KICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgnLicsICcnKTsNCiAgICAgICAgeSA9IG5ldyBDdG9yKDEpOw0KICAgICAgICB5LmUgPSBzdHIubGVuZ3RoIC0gaTsNCiAgICAgICAgeS5kID0gY29udmVydEJhc2UoZmluaXRlVG9TdHJpbmcoeSksIDEwLCBiYXNlKTsNCiAgICAgICAgeS5lID0geS5kLmxlbmd0aDsNCiAgICAgIH0NCg0KICAgICAgeGQgPSBjb252ZXJ0QmFzZShzdHIsIDEwLCBiYXNlKTsNCiAgICAgIGUgPSBsZW4gPSB4ZC5sZW5ndGg7DQoNCiAgICAgIC8vIFJlbW92ZSB0cmFpbGluZyB6ZXJvcy4NCiAgICAgIGZvciAoOyB4ZFstLWxlbl0gPT0gMDspIHhkLnBvcCgpOw0KDQogICAgICBpZiAoIXhkWzBdKSB7DQogICAgICAgIHN0ciA9IGlzRXhwID8gJzBwKzAnIDogJzAnOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgaWYgKGkgPCAwKSB7DQogICAgICAgICAgZS0tOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIHggPSBuZXcgQ3Rvcih4KTsNCiAgICAgICAgICB4LmQgPSB4ZDsNCiAgICAgICAgICB4LmUgPSBlOw0KICAgICAgICAgIHggPSBkaXZpZGUoeCwgeSwgc2QsIHJtLCAwLCBiYXNlKTsNCiAgICAgICAgICB4ZCA9IHguZDsNCiAgICAgICAgICBlID0geC5lOw0KICAgICAgICAgIHJvdW5kVXAgPSBpbmV4YWN0Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gVGhlIHJvdW5kaW5nIGRpZ2l0LCBpLmUuIHRoZSBkaWdpdCBhZnRlciB0aGUgZGlnaXQgdGhhdCBtYXkgYmUgcm91bmRlZCB1cC4NCiAgICAgICAgaSA9IHhkW3NkXTsNCiAgICAgICAgayA9IGJhc2UgLyAyOw0KICAgICAgICByb3VuZFVwID0gcm91bmRVcCB8fCB4ZFtzZCArIDFdICE9PSB2b2lkIDA7DQoNCiAgICAgICAgcm91bmRVcCA9IHJtIDwgNA0KICAgICAgICAgID8gKGkgIT09IHZvaWQgMCB8fCByb3VuZFVwKSAmJiAocm0gPT09IDAgfHwgcm0gPT09ICh4LnMgPCAwID8gMyA6IDIpKQ0KICAgICAgICAgIDogaSA+IGsgfHwgaSA9PT0gayAmJiAocm0gPT09IDQgfHwgcm91bmRVcCB8fCBybSA9PT0gNiAmJiB4ZFtzZCAtIDFdICYgMSB8fA0KICAgICAgICAgICAgcm0gPT09ICh4LnMgPCAwID8gOCA6IDcpKTsNCg0KICAgICAgICB4ZC5sZW5ndGggPSBzZDsNCg0KICAgICAgICBpZiAocm91bmRVcCkgew0KDQogICAgICAgICAgLy8gUm91bmRpbmcgdXAgbWF5IG1lYW4gdGhlIHByZXZpb3VzIGRpZ2l0IGhhcyB0byBiZSByb3VuZGVkIHVwIGFuZCBzbyBvbi4NCiAgICAgICAgICBmb3IgKDsgKyt4ZFstLXNkXSA+IGJhc2UgLSAxOykgew0KICAgICAgICAgICAgeGRbc2RdID0gMDsNCiAgICAgICAgICAgIGlmICghc2QpIHsNCiAgICAgICAgICAgICAgKytlOw0KICAgICAgICAgICAgICB4ZC51bnNoaWZ0KDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERldGVybWluZSB0cmFpbGluZyB6ZXJvcy4NCiAgICAgICAgZm9yIChsZW4gPSB4ZC5sZW5ndGg7ICF4ZFtsZW4gLSAxXTsgLS1sZW4pOw0KDQogICAgICAgIC8vIEUuZy4gWzQsIDExLCAxNV0gYmVjb21lcyA0YmYuDQogICAgICAgIGZvciAoaSA9IDAsIHN0ciA9ICcnOyBpIDwgbGVuOyBpKyspIHN0ciArPSBOVU1FUkFMUy5jaGFyQXQoeGRbaV0pOw0KDQogICAgICAgIC8vIEFkZCBiaW5hcnkgZXhwb25lbnQgc3VmZml4Pw0KICAgICAgICBpZiAoaXNFeHApIHsNCiAgICAgICAgICBpZiAobGVuID4gMSkgew0KICAgICAgICAgICAgaWYgKGJhc2VPdXQgPT0gMTYgfHwgYmFzZU91dCA9PSA4KSB7DQogICAgICAgICAgICAgIGkgPSBiYXNlT3V0ID09IDE2ID8gNCA6IDM7DQogICAgICAgICAgICAgIGZvciAoLS1sZW47IGxlbiAlIGk7IGxlbisrKSBzdHIgKz0gJzAnOw0KICAgICAgICAgICAgICB4ZCA9IGNvbnZlcnRCYXNlKHN0ciwgYmFzZSwgYmFzZU91dCk7DQogICAgICAgICAgICAgIGZvciAobGVuID0geGQubGVuZ3RoOyAheGRbbGVuIC0gMV07IC0tbGVuKTsNCg0KICAgICAgICAgICAgICAvLyB4ZFswXSB3aWxsIGFsd2F5cyBiZSBiZSAxDQogICAgICAgICAgICAgIGZvciAoaSA9IDEsIHN0ciA9ICcxLic7IGkgPCBsZW47IGkrKykgc3RyICs9IE5VTUVSQUxTLmNoYXJBdCh4ZFtpXSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICBzdHIgPSBzdHIuY2hhckF0KDApICsgJy4nICsgc3RyLnNsaWNlKDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCg0KICAgICAgICAgIHN0ciA9ICBzdHIgKyAoZSA8IDAgPyAncCcgOiAncCsnKSArIGU7DQogICAgICAgIH0gZWxzZSBpZiAoZSA8IDApIHsNCiAgICAgICAgICBmb3IgKDsgKytlOykgc3RyID0gJzAnICsgc3RyOw0KICAgICAgICAgIHN0ciA9ICcwLicgKyBzdHI7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgaWYgKCsrZSA+IGxlbikgZm9yIChlIC09IGxlbjsgZS0tIDspIHN0ciArPSAnMCc7DQogICAgICAgICAgZWxzZSBpZiAoZSA8IGxlbikgc3RyID0gc3RyLnNsaWNlKDAsIGUpICsgJy4nICsgc3RyLnNsaWNlKGUpOw0KICAgICAgICB9DQogICAgICB9DQoNCiAgICAgIHN0ciA9IChiYXNlT3V0ID09IDE2ID8gJzB4JyA6IGJhc2VPdXQgPT0gMiA/ICcwYicgOiBiYXNlT3V0ID09IDggPyAnMG8nIDogJycpICsgc3RyOw0KICAgIH0NCg0KICAgIHJldHVybiB4LnMgPCAwID8gJy0nICsgc3RyIDogc3RyOw0KICB9DQoNCg0KICAvLyBEb2VzIG5vdCBzdHJpcCB0cmFpbGluZyB6ZXJvcy4NCiAgZnVuY3Rpb24gdHJ1bmNhdGUoYXJyLCBsZW4pIHsNCiAgICBpZiAoYXJyLmxlbmd0aCA+IGxlbikgew0KICAgICAgYXJyLmxlbmd0aCA9IGxlbjsNCiAgICAgIHJldHVybiB0cnVlOw0KICAgIH0NCiAgfQ0KDQoNCiAgLy8gRGVjaW1hbCBtZXRob2RzDQoNCg0KICAvKg0KICAgKiAgYWJzDQogICAqICBhY29zDQogICAqICBhY29zaA0KICAgKiAgYWRkDQogICAqICBhc2luDQogICAqICBhc2luaA0KICAgKiAgYXRhbg0KICAgKiAgYXRhbmgNCiAgICogIGF0YW4yDQogICAqICBjYnJ0DQogICAqICBjZWlsDQogICAqICBjbGFtcA0KICAgKiAgY2xvbmUNCiAgICogIGNvbmZpZw0KICAgKiAgY29zDQogICAqICBjb3NoDQogICAqICBkaXYNCiAgICogIGV4cA0KICAgKiAgZmxvb3INCiAgICogIGh5cG90DQogICAqICBsbg0KICAgKiAgbG9nDQogICAqICBsb2cyDQogICAqICBsb2cxMA0KICAgKiAgbWF4DQogICAqICBtaW4NCiAgICogIG1vZA0KICAgKiAgbXVsDQogICAqICBwb3cNCiAgICogIHJhbmRvbQ0KICAgKiAgcm91bmQNCiAgICogIHNldA0KICAgKiAgc2lnbg0KICAgKiAgc2luDQogICAqICBzaW5oDQogICAqICBzcXJ0DQogICAqICBzdWINCiAgICogIHN1bQ0KICAgKiAgdGFuDQogICAqICB0YW5oDQogICAqICB0cnVuYw0KICAgKi8NCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiBgeGAuDQogICAqDQogICAqIHgge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9DQogICAqDQogICAqLw0KICBmdW5jdGlvbiBhYnMoeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5hYnMoKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGFyY2Nvc2luZSBpbiByYWRpYW5zIG9mIGB4YC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGFjb3MoeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5hY29zKCk7DQogIH0NCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBpbnZlcnNlIG9mIHRoZSBoeXBlcmJvbGljIGNvc2luZSBvZiBgeGAsIHJvdW5kZWQgdG8NCiAgICogYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gQSB2YWx1ZSBpbiByYWRpYW5zLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gYWNvc2goeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5hY29zaCgpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgc3VtIG9mIGB4YCBhbmQgYHlgLCByb3VuZGVkIHRvIGBwcmVjaXNpb25gIHNpZ25pZmljYW50DQogICAqIGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqIHgge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9DQogICAqIHkge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9DQogICAqDQogICAqLw0KICBmdW5jdGlvbiBhZGQoeCwgeSkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5wbHVzKHkpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgYXJjc2luZSBpbiByYWRpYW5zIG9mIGB4YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYA0KICAgKiBzaWduaWZpY2FudCBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gYXNpbih4KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLmFzaW4oKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGludmVyc2Ugb2YgdGhlIGh5cGVyYm9saWMgc2luZSBvZiBgeGAsIHJvdW5kZWQgdG8NCiAgICogYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gQSB2YWx1ZSBpbiByYWRpYW5zLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gYXNpbmgoeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5hc2luaCgpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgYXJjdGFuZ2VudCBpbiByYWRpYW5zIG9mIGB4YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYA0KICAgKiBzaWduaWZpY2FudCBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gYXRhbih4KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLmF0YW4oKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGludmVyc2Ugb2YgdGhlIGh5cGVyYm9saWMgdGFuZ2VudCBvZiBgeGAsIHJvdW5kZWQgdG8NCiAgICogYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gQSB2YWx1ZSBpbiByYWRpYW5zLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gYXRhbmgoeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5hdGFuaCgpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgYXJjdGFuZ2VudCBpbiByYWRpYW5zIG9mIGB5L3hgIGluIHRoZSByYW5nZSAtcGkgdG8gcGkNCiAgICogKGluY2x1c2l2ZSksIHJvdW5kZWQgdG8gYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogRG9tYWluOiBbLUluZmluaXR5LCBJbmZpbml0eV0NCiAgICogUmFuZ2U6IFstcGksIHBpXQ0KICAgKg0KICAgKiB5IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBUaGUgeS1jb29yZGluYXRlLg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBUaGUgeC1jb29yZGluYXRlLg0KICAgKg0KICAgKiBhdGFuMijCsTAsIC0wKSAgICAgICAgICAgICAgID0gwrFwaQ0KICAgKiBhdGFuMijCsTAsICswKSAgICAgICAgICAgICAgID0gwrEwDQogICAqIGF0YW4yKMKxMCwgLXgpICAgICAgICAgICAgICAgPSDCsXBpIGZvciB4ID4gMA0KICAgKiBhdGFuMijCsTAsIHgpICAgICAgICAgICAgICAgID0gwrEwIGZvciB4ID4gMA0KICAgKiBhdGFuMigteSwgwrEwKSAgICAgICAgICAgICAgID0gLXBpLzIgZm9yIHkgPiAwDQogICAqIGF0YW4yKHksIMKxMCkgICAgICAgICAgICAgICAgPSBwaS8yIGZvciB5ID4gMA0KICAgKiBhdGFuMijCsXksIC1JbmZpbml0eSkgICAgICAgID0gwrFwaSBmb3IgZmluaXRlIHkgPiAwDQogICAqIGF0YW4yKMKxeSwgK0luZmluaXR5KSAgICAgICAgPSDCsTAgZm9yIGZpbml0ZSB5ID4gMA0KICAgKiBhdGFuMijCsUluZmluaXR5LCB4KSAgICAgICAgID0gwrFwaS8yIGZvciBmaW5pdGUgeA0KICAgKiBhdGFuMijCsUluZmluaXR5LCAtSW5maW5pdHkpID0gwrEzKnBpLzQNCiAgICogYXRhbjIowrFJbmZpbml0eSwgK0luZmluaXR5KSA9IMKxcGkvNA0KICAgKiBhdGFuMihOYU4sIHgpID0gTmFODQogICAqIGF0YW4yKHksIE5hTikgPSBOYU4NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGF0YW4yKHksIHgpIHsNCiAgICB5ID0gbmV3IHRoaXMoeSk7DQogICAgeCA9IG5ldyB0aGlzKHgpOw0KICAgIHZhciByLA0KICAgICAgcHIgPSB0aGlzLnByZWNpc2lvbiwNCiAgICAgIHJtID0gdGhpcy5yb3VuZGluZywNCiAgICAgIHdwciA9IHByICsgNDsNCg0KICAgIC8vIEVpdGhlciBOYU4NCiAgICBpZiAoIXkucyB8fCAheC5zKSB7DQogICAgICByID0gbmV3IHRoaXMoTmFOKTsNCg0KICAgIC8vIEJvdGggwrFJbmZpbml0eQ0KICAgIH0gZWxzZSBpZiAoIXkuZCAmJiAheC5kKSB7DQogICAgICByID0gZ2V0UGkodGhpcywgd3ByLCAxKS50aW1lcyh4LnMgPiAwID8gMC4yNSA6IDAuNzUpOw0KICAgICAgci5zID0geS5zOw0KDQogICAgLy8geCBpcyDCsUluZmluaXR5IG9yIHkgaXMgwrEwDQogICAgfSBlbHNlIGlmICgheC5kIHx8IHkuaXNaZXJvKCkpIHsNCiAgICAgIHIgPSB4LnMgPCAwID8gZ2V0UGkodGhpcywgcHIsIHJtKSA6IG5ldyB0aGlzKDApOw0KICAgICAgci5zID0geS5zOw0KDQogICAgLy8geSBpcyDCsUluZmluaXR5IG9yIHggaXMgwrEwDQogICAgfSBlbHNlIGlmICgheS5kIHx8IHguaXNaZXJvKCkpIHsNCiAgICAgIHIgPSBnZXRQaSh0aGlzLCB3cHIsIDEpLnRpbWVzKDAuNSk7DQogICAgICByLnMgPSB5LnM7DQoNCiAgICAvLyBCb3RoIG5vbi16ZXJvIGFuZCBmaW5pdGUNCiAgICB9IGVsc2UgaWYgKHgucyA8IDApIHsNCiAgICAgIHRoaXMucHJlY2lzaW9uID0gd3ByOw0KICAgICAgdGhpcy5yb3VuZGluZyA9IDE7DQogICAgICByID0gdGhpcy5hdGFuKGRpdmlkZSh5LCB4LCB3cHIsIDEpKTsNCiAgICAgIHggPSBnZXRQaSh0aGlzLCB3cHIsIDEpOw0KICAgICAgdGhpcy5wcmVjaXNpb24gPSBwcjsNCiAgICAgIHRoaXMucm91bmRpbmcgPSBybTsNCiAgICAgIHIgPSB5LnMgPCAwID8gci5taW51cyh4KSA6IHIucGx1cyh4KTsNCiAgICB9IGVsc2Ugew0KICAgICAgciA9IHRoaXMuYXRhbihkaXZpZGUoeSwgeCwgd3ByLCAxKSk7DQogICAgfQ0KDQogICAgcmV0dXJuIHI7DQogIH0NCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBjdWJlIHJvb3Qgb2YgYHhgLCByb3VuZGVkIHRvIGBwcmVjaXNpb25gIHNpZ25pZmljYW50DQogICAqIGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqIHgge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9DQogICAqDQogICAqLw0KICBmdW5jdGlvbiBjYnJ0KHgpIHsNCiAgICByZXR1cm4gbmV3IHRoaXMoeCkuY2JydCgpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyBgeGAgcm91bmRlZCB0byBhbiBpbnRlZ2VyIHVzaW5nIGBST1VORF9DRUlMYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGNlaWwoeCkgew0KICAgIHJldHVybiBmaW5hbGlzZSh4ID0gbmV3IHRoaXMoeCksIHguZSArIDEsIDIpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyBgeGAgY2xhbXBlZCB0byB0aGUgcmFuZ2UgZGVsaW5lYXRlZCBieSBgbWluYCBhbmQgYG1heGAuDQogICAqDQogICAqIHgge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9DQogICAqIG1pbiB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICogbWF4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gY2xhbXAoeCwgbWluLCBtYXgpIHsNCiAgICByZXR1cm4gbmV3IHRoaXMoeCkuY2xhbXAobWluLCBtYXgpOw0KICB9DQoNCg0KICAvKg0KICAgKiBDb25maWd1cmUgZ2xvYmFsIHNldHRpbmdzIGZvciBhIERlY2ltYWwgY29uc3RydWN0b3IuDQogICAqDQogICAqIGBvYmpgIGlzIGFuIG9iamVjdCB3aXRoIG9uZSBvciBtb3JlIG9mIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcywNCiAgICoNCiAgICogICBwcmVjaXNpb24gIHtudW1iZXJ9DQogICAqICAgcm91bmRpbmcgICB7bnVtYmVyfQ0KICAgKiAgIHRvRXhwTmVnICAge251bWJlcn0NCiAgICogICB0b0V4cFBvcyAgIHtudW1iZXJ9DQogICAqICAgbWF4RSAgICAgICB7bnVtYmVyfQ0KICAgKiAgIG1pbkUgICAgICAge251bWJlcn0NCiAgICogICBtb2R1bG8gICAgIHtudW1iZXJ9DQogICAqICAgY3J5cHRvICAgICB7Ym9vbGVhbnxudW1iZXJ9DQogICAqICAgZGVmYXVsdHMgICB7dHJ1ZX0NCiAgICoNCiAgICogRS5nLiBEZWNpbWFsLmNvbmZpZyh7IHByZWNpc2lvbjogMjAsIHJvdW5kaW5nOiA0IH0pDQogICAqDQogICAqLw0KICBmdW5jdGlvbiBjb25maWcob2JqKSB7DQogICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHRocm93IEVycm9yKGRlY2ltYWxFcnJvciArICdPYmplY3QgZXhwZWN0ZWQnKTsNCiAgICB2YXIgaSwgcCwgdiwNCiAgICAgIHVzZURlZmF1bHRzID0gb2JqLmRlZmF1bHRzID09PSB0cnVlLA0KICAgICAgcHMgPSBbDQogICAgICAgICdwcmVjaXNpb24nLCAxLCBNQVhfRElHSVRTLA0KICAgICAgICAncm91bmRpbmcnLCAwLCA4LA0KICAgICAgICAndG9FeHBOZWcnLCAtRVhQX0xJTUlULCAwLA0KICAgICAgICAndG9FeHBQb3MnLCAwLCBFWFBfTElNSVQsDQogICAgICAgICdtYXhFJywgMCwgRVhQX0xJTUlULA0KICAgICAgICAnbWluRScsIC1FWFBfTElNSVQsIDAsDQogICAgICAgICdtb2R1bG8nLCAwLCA5DQogICAgICBdOw0KDQogICAgZm9yIChpID0gMDsgaSA8IHBzLmxlbmd0aDsgaSArPSAzKSB7DQogICAgICBpZiAocCA9IHBzW2ldLCB1c2VEZWZhdWx0cykgdGhpc1twXSA9IERFRkFVTFRTW3BdOw0KICAgICAgaWYgKCh2ID0gb2JqW3BdKSAhPT0gdm9pZCAwKSB7DQogICAgICAgIGlmIChtYXRoZmxvb3IodikgPT09IHYgJiYgdiA+PSBwc1tpICsgMV0gJiYgdiA8PSBwc1tpICsgMl0pIHRoaXNbcF0gPSB2Ow0KICAgICAgICBlbHNlIHRocm93IEVycm9yKGludmFsaWRBcmd1bWVudCArIHAgKyAnOiAnICsgdik7DQogICAgICB9DQogICAgfQ0KDQogICAgaWYgKHAgPSAnY3J5cHRvJywgdXNlRGVmYXVsdHMpIHRoaXNbcF0gPSBERUZBVUxUU1twXTsNCiAgICBpZiAoKHYgPSBvYmpbcF0pICE9PSB2b2lkIDApIHsNCiAgICAgIGlmICh2ID09PSB0cnVlIHx8IHYgPT09IGZhbHNlIHx8IHYgPT09IDAgfHwgdiA9PT0gMSkgew0KICAgICAgICBpZiAodikgew0KICAgICAgICAgIGlmICh0eXBlb2YgY3J5cHRvICE9ICd1bmRlZmluZWQnICYmIGNyeXB0byAmJg0KICAgICAgICAgICAgKGNyeXB0by5nZXRSYW5kb21WYWx1ZXMgfHwgY3J5cHRvLnJhbmRvbUJ5dGVzKSkgew0KICAgICAgICAgICAgdGhpc1twXSA9IHRydWU7DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHRocm93IEVycm9yKGNyeXB0b1VuYXZhaWxhYmxlKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgdGhpc1twXSA9IGZhbHNlOw0KICAgICAgICB9DQogICAgICB9IGVsc2Ugew0KICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkQXJndW1lbnQgKyBwICsgJzogJyArIHYpOw0KICAgICAgfQ0KICAgIH0NCg0KICAgIHJldHVybiB0aGlzOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgY29zaW5lIG9mIGB4YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYCBzaWduaWZpY2FudA0KICAgKiBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBBIHZhbHVlIGluIHJhZGlhbnMuDQogICAqDQogICAqLw0KICBmdW5jdGlvbiBjb3MoeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5jb3MoKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGh5cGVyYm9saWMgY29zaW5lIG9mIGB4YCwgcm91bmRlZCB0byBwcmVjaXNpb24NCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gQSB2YWx1ZSBpbiByYWRpYW5zLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gY29zaCh4KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLmNvc2goKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogQ3JlYXRlIGFuZCByZXR1cm4gYSBEZWNpbWFsIGNvbnN0cnVjdG9yIHdpdGggdGhlIHNhbWUgY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIGFzIHRoaXMgRGVjaW1hbA0KICAgKiBjb25zdHJ1Y3Rvci4NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGNsb25lKG9iaikgew0KICAgIHZhciBpLCBwLCBwczsNCg0KICAgIC8qDQogICAgICogVGhlIERlY2ltYWwgY29uc3RydWN0b3IgYW5kIGV4cG9ydGVkIGZ1bmN0aW9uLg0KICAgICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIGluc3RhbmNlLg0KICAgICAqDQogICAgICogdiB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gQSBudW1lcmljIHZhbHVlLg0KICAgICAqDQogICAgICovDQogICAgZnVuY3Rpb24gRGVjaW1hbCh2KSB7DQogICAgICB2YXIgZSwgaSwgdCwNCiAgICAgICAgeCA9IHRoaXM7DQoNCiAgICAgIC8vIERlY2ltYWwgY2FsbGVkIHdpdGhvdXQgbmV3Lg0KICAgICAgaWYgKCEoeCBpbnN0YW5jZW9mIERlY2ltYWwpKSByZXR1cm4gbmV3IERlY2ltYWwodik7DQoNCiAgICAgIC8vIFJldGFpbiBhIHJlZmVyZW5jZSB0byB0aGlzIERlY2ltYWwgY29uc3RydWN0b3IsIGFuZCBzaGFkb3cgRGVjaW1hbC5wcm90b3R5cGUuY29uc3RydWN0b3INCiAgICAgIC8vIHdoaWNoIHBvaW50cyB0byBPYmplY3QuDQogICAgICB4LmNvbnN0cnVjdG9yID0gRGVjaW1hbDsNCg0KICAgICAgaWYgKGlzRGVjaW1hbEluc3RhbmNlKHYpKSB7DQogICAgICAgIHgucyA9IHYuczsNCg0KICAgICAgICBpZiAoZXh0ZXJuYWwpIHsNCiAgICAgICAgICBpZiAoIXYuZCB8fCB2LmUgPiBEZWNpbWFsLm1heEUpIHsNCg0KICAgICAgICAgICAgLy8gSW5maW5pdHkuDQogICAgICAgICAgICB4LmUgPSBOYU47DQogICAgICAgICAgICB4LmQgPSBudWxsOw0KICAgICAgICAgIH0gZWxzZSBpZiAodi5lIDwgRGVjaW1hbC5taW5FKSB7DQoNCiAgICAgICAgICAgIC8vIFplcm8uDQogICAgICAgICAgICB4LmUgPSAwOw0KICAgICAgICAgICAgeC5kID0gWzBdOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB4LmUgPSB2LmU7DQogICAgICAgICAgICB4LmQgPSB2LmQuc2xpY2UoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgeC5lID0gdi5lOw0KICAgICAgICAgIHguZCA9IHYuZCA/IHYuZC5zbGljZSgpIDogdi5kOw0KICAgICAgICB9DQoNCiAgICAgICAgcmV0dXJuOw0KICAgICAgfQ0KDQogICAgICB0ID0gdHlwZW9mIHY7DQoNCiAgICAgIGlmICh0ID09PSAnbnVtYmVyJykgew0KICAgICAgICBpZiAodiA9PT0gMCkgew0KICAgICAgICAgIHgucyA9IDEgLyB2IDwgMCA/IC0xIDogMTsNCiAgICAgICAgICB4LmUgPSAwOw0KICAgICAgICAgIHguZCA9IFswXTsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCg0KICAgICAgICBpZiAodiA8IDApIHsNCiAgICAgICAgICB2ID0gLXY7DQogICAgICAgICAgeC5zID0gLTE7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgeC5zID0gMTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEZhc3QgcGF0aCBmb3Igc21hbGwgaW50ZWdlcnMuDQogICAgICAgIGlmICh2ID09PSB+fnYgJiYgdiA8IDFlNykgew0KICAgICAgICAgIGZvciAoZSA9IDAsIGkgPSB2OyBpID49IDEwOyBpIC89IDEwKSBlKys7DQoNCiAgICAgICAgICBpZiAoZXh0ZXJuYWwpIHsNCiAgICAgICAgICAgIGlmIChlID4gRGVjaW1hbC5tYXhFKSB7DQogICAgICAgICAgICAgIHguZSA9IE5hTjsNCiAgICAgICAgICAgICAgeC5kID0gbnVsbDsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoZSA8IERlY2ltYWwubWluRSkgew0KICAgICAgICAgICAgICB4LmUgPSAwOw0KICAgICAgICAgICAgICB4LmQgPSBbMF07DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICB4LmUgPSBlOw0KICAgICAgICAgICAgICB4LmQgPSBbdl07DQogICAgICAgICAgICB9DQogICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHguZSA9IGU7DQogICAgICAgICAgICB4LmQgPSBbdl07DQogICAgICAgICAgfQ0KDQogICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gSW5maW5pdHkgb3IgTmFOPw0KICAgICAgICBpZiAodiAqIDAgIT09IDApIHsNCiAgICAgICAgICBpZiAoIXYpIHgucyA9IE5hTjsNCiAgICAgICAgICB4LmUgPSBOYU47DQogICAgICAgICAgeC5kID0gbnVsbDsNCiAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCg0KICAgICAgICByZXR1cm4gcGFyc2VEZWNpbWFsKHgsIHYudG9TdHJpbmcoKSk7DQogICAgICB9DQoNCiAgICAgIGlmICh0ID09PSAnc3RyaW5nJykgew0KICAgICAgICBpZiAoKGkgPSB2LmNoYXJDb2RlQXQoMCkpID09PSA0NSkgeyAgLy8gbWludXMgc2lnbg0KICAgICAgICAgIHYgPSB2LnNsaWNlKDEpOw0KICAgICAgICAgIHgucyA9IC0xOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIGlmIChpID09PSA0MykgdiA9IHYuc2xpY2UoMSk7ICAvLyBwbHVzIHNpZ24NCiAgICAgICAgICB4LnMgPSAxOw0KICAgICAgICB9DQoNCiAgICAgICAgcmV0dXJuIGlzRGVjaW1hbC50ZXN0KHYpID8gcGFyc2VEZWNpbWFsKHgsIHYpIDogcGFyc2VPdGhlcih4LCB2KTsNCiAgICAgIH0NCg0KICAgICAgaWYgKHQgPT09ICdiaWdpbnQnKSB7DQogICAgICAgIGlmICh2IDwgMCkgew0KICAgICAgICAgIHYgPSAtdjsNCiAgICAgICAgICB4LnMgPSAtMTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB4LnMgPSAxOw0KICAgICAgICB9DQoNCiAgICAgICAgcmV0dXJuIHBhcnNlRGVjaW1hbCh4LCB2LnRvU3RyaW5nKCkpOw0KICAgICAgfQ0KDQogICAgICB0aHJvdyBFcnJvcihpbnZhbGlkQXJndW1lbnQgKyB2KTsNCiAgICB9DQoNCiAgICBEZWNpbWFsLnByb3RvdHlwZSA9IFA7DQoNCiAgICBEZWNpbWFsLlJPVU5EX1VQID0gMDsNCiAgICBEZWNpbWFsLlJPVU5EX0RPV04gPSAxOw0KICAgIERlY2ltYWwuUk9VTkRfQ0VJTCA9IDI7DQogICAgRGVjaW1hbC5ST1VORF9GTE9PUiA9IDM7DQogICAgRGVjaW1hbC5ST1VORF9IQUxGX1VQID0gNDsNCiAgICBEZWNpbWFsLlJPVU5EX0hBTEZfRE9XTiA9IDU7DQogICAgRGVjaW1hbC5ST1VORF9IQUxGX0VWRU4gPSA2Ow0KICAgIERlY2ltYWwuUk9VTkRfSEFMRl9DRUlMID0gNzsNCiAgICBEZWNpbWFsLlJPVU5EX0hBTEZfRkxPT1IgPSA4Ow0KICAgIERlY2ltYWwuRVVDTElEID0gOTsNCg0KICAgIERlY2ltYWwuY29uZmlnID0gRGVjaW1hbC5zZXQgPSBjb25maWc7DQogICAgRGVjaW1hbC5jbG9uZSA9IGNsb25lOw0KICAgIERlY2ltYWwuaXNEZWNpbWFsID0gaXNEZWNpbWFsSW5zdGFuY2U7DQoNCiAgICBEZWNpbWFsLmFicyA9IGFiczsNCiAgICBEZWNpbWFsLmFjb3MgPSBhY29zOw0KICAgIERlY2ltYWwuYWNvc2ggPSBhY29zaDsgICAgICAgIC8vIEVTNg0KICAgIERlY2ltYWwuYWRkID0gYWRkOw0KICAgIERlY2ltYWwuYXNpbiA9IGFzaW47DQogICAgRGVjaW1hbC5hc2luaCA9IGFzaW5oOyAgICAgICAgLy8gRVM2DQogICAgRGVjaW1hbC5hdGFuID0gYXRhbjsNCiAgICBEZWNpbWFsLmF0YW5oID0gYXRhbmg7ICAgICAgICAvLyBFUzYNCiAgICBEZWNpbWFsLmF0YW4yID0gYXRhbjI7DQogICAgRGVjaW1hbC5jYnJ0ID0gY2JydDsgICAgICAgICAgLy8gRVM2DQogICAgRGVjaW1hbC5jZWlsID0gY2VpbDsNCiAgICBEZWNpbWFsLmNsYW1wID0gY2xhbXA7DQogICAgRGVjaW1hbC5jb3MgPSBjb3M7DQogICAgRGVjaW1hbC5jb3NoID0gY29zaDsgICAgICAgICAgLy8gRVM2DQogICAgRGVjaW1hbC5kaXYgPSBkaXY7DQogICAgRGVjaW1hbC5leHAgPSBleHA7DQogICAgRGVjaW1hbC5mbG9vciA9IGZsb29yOw0KICAgIERlY2ltYWwuaHlwb3QgPSBoeXBvdDsgICAgICAgIC8vIEVTNg0KICAgIERlY2ltYWwubG4gPSBsbjsNCiAgICBEZWNpbWFsLmxvZyA9IGxvZzsNCiAgICBEZWNpbWFsLmxvZzEwID0gbG9nMTA7ICAgICAgICAvLyBFUzYNCiAgICBEZWNpbWFsLmxvZzIgPSBsb2cyOyAgICAgICAgICAvLyBFUzYNCiAgICBEZWNpbWFsLm1heCA9IG1heDsNCiAgICBEZWNpbWFsLm1pbiA9IG1pbjsNCiAgICBEZWNpbWFsLm1vZCA9IG1vZDsNCiAgICBEZWNpbWFsLm11bCA9IG11bDsNCiAgICBEZWNpbWFsLnBvdyA9IHBvdzsNCiAgICBEZWNpbWFsLnJhbmRvbSA9IHJhbmRvbTsNCiAgICBEZWNpbWFsLnJvdW5kID0gcm91bmQ7DQogICAgRGVjaW1hbC5zaWduID0gc2lnbjsgICAgICAgICAgLy8gRVM2DQogICAgRGVjaW1hbC5zaW4gPSBzaW47DQogICAgRGVjaW1hbC5zaW5oID0gc2luaDsgICAgICAgICAgLy8gRVM2DQogICAgRGVjaW1hbC5zcXJ0ID0gc3FydDsNCiAgICBEZWNpbWFsLnN1YiA9IHN1YjsNCiAgICBEZWNpbWFsLnN1bSA9IHN1bTsNCiAgICBEZWNpbWFsLnRhbiA9IHRhbjsNCiAgICBEZWNpbWFsLnRhbmggPSB0YW5oOyAgICAgICAgICAvLyBFUzYNCiAgICBEZWNpbWFsLnRydW5jID0gdHJ1bmM7ICAgICAgICAvLyBFUzYNCg0KICAgIGlmIChvYmogPT09IHZvaWQgMCkgb2JqID0ge307DQogICAgaWYgKG9iaikgew0KICAgICAgaWYgKG9iai5kZWZhdWx0cyAhPT0gdHJ1ZSkgew0KICAgICAgICBwcyA9IFsncHJlY2lzaW9uJywgJ3JvdW5kaW5nJywgJ3RvRXhwTmVnJywgJ3RvRXhwUG9zJywgJ21heEUnLCAnbWluRScsICdtb2R1bG8nLCAnY3J5cHRvJ107DQogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwcy5sZW5ndGg7KSBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShwID0gcHNbaSsrXSkpIG9ialtwXSA9IHRoaXNbcF07DQogICAgICB9DQogICAgfQ0KDQogICAgRGVjaW1hbC5jb25maWcob2JqKTsNCg0KICAgIHJldHVybiBEZWNpbWFsOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyBgeGAgZGl2aWRlZCBieSBgeWAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQNCiAgICogZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICogeSB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGRpdih4LCB5KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLmRpdih5KTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG5hdHVyYWwgZXhwb25lbnRpYWwgb2YgYHhgLCByb3VuZGVkIHRvIGBwcmVjaXNpb25gDQogICAqIHNpZ25pZmljYW50IGRpZ2l0cyB1c2luZyByb3VuZGluZyBtb2RlIGByb3VuZGluZ2AuDQogICAqDQogICAqIHgge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9IFRoZSBwb3dlciB0byB3aGljaCB0byByYWlzZSB0aGUgYmFzZSBvZiB0aGUgbmF0dXJhbCBsb2cuDQogICAqDQogICAqLw0KICBmdW5jdGlvbiBleHAoeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5leHAoKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgYHhgIHJvdW5kIHRvIGFuIGludGVnZXIgdXNpbmcgYFJPVU5EX0ZMT09SYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGZsb29yKHgpIHsNCiAgICByZXR1cm4gZmluYWxpc2UoeCA9IG5ldyB0aGlzKHgpLCB4LmUgKyAxLCAzKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHNxdWFyZSByb290IG9mIHRoZSBzdW0gb2YgdGhlIHNxdWFyZXMgb2YgdGhlIGFyZ3VtZW50cywNCiAgICogcm91bmRlZCB0byBgcHJlY2lzaW9uYCBzaWduaWZpY2FudCBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiBoeXBvdChhLCBiLCAuLi4pID0gc3FydChhXjIgKyBiXjIgKyAuLi4pDQogICAqDQogICAqIGFyZ3VtZW50cyB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGh5cG90KCkgew0KICAgIHZhciBpLCBuLA0KICAgICAgdCA9IG5ldyB0aGlzKDApOw0KDQogICAgZXh0ZXJuYWwgPSBmYWxzZTsNCg0KICAgIGZvciAoaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOykgew0KICAgICAgbiA9IG5ldyB0aGlzKGFyZ3VtZW50c1tpKytdKTsNCiAgICAgIGlmICghbi5kKSB7DQogICAgICAgIGlmIChuLnMpIHsNCiAgICAgICAgICBleHRlcm5hbCA9IHRydWU7DQogICAgICAgICAgcmV0dXJuIG5ldyB0aGlzKDEgLyAwKTsNCiAgICAgICAgfQ0KICAgICAgICB0ID0gbjsNCiAgICAgIH0gZWxzZSBpZiAodC5kKSB7DQogICAgICAgIHQgPSB0LnBsdXMobi50aW1lcyhuKSk7DQogICAgICB9DQogICAgfQ0KDQogICAgZXh0ZXJuYWwgPSB0cnVlOw0KDQogICAgcmV0dXJuIHQuc3FydCgpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gdHJ1ZSBpZiBvYmplY3QgaXMgYSBEZWNpbWFsIGluc3RhbmNlICh3aGVyZSBEZWNpbWFsIGlzIGFueSBEZWNpbWFsIGNvbnN0cnVjdG9yKSwNCiAgICogb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGlzRGVjaW1hbEluc3RhbmNlKG9iaikgew0KICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBEZWNpbWFsIHx8IG9iaiAmJiBvYmoudG9TdHJpbmdUYWcgPT09IHRhZyB8fCBmYWxzZTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIGB4YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYA0KICAgKiBzaWduaWZpY2FudCBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gbG4oeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5sbigpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgbG9nIG9mIGB4YCB0byB0aGUgYmFzZSBgeWAsIG9yIHRvIGJhc2UgMTAgaWYgbm8gYmFzZQ0KICAgKiBpcyBzcGVjaWZpZWQsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogbG9nW3ldKHgpDQogICAqDQogICAqIHgge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9IFRoZSBhcmd1bWVudCBvZiB0aGUgbG9nYXJpdGhtLg0KICAgKiB5IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBUaGUgYmFzZSBvZiB0aGUgbG9nYXJpdGhtLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gbG9nKHgsIHkpIHsNCiAgICByZXR1cm4gbmV3IHRoaXMoeCkubG9nKHkpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgYmFzZSAyIGxvZ2FyaXRobSBvZiBgeGAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGxvZzIoeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5sb2coMik7DQogIH0NCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBiYXNlIDEwIGxvZ2FyaXRobSBvZiBgeGAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIGxvZzEwKHgpIHsNCiAgICByZXR1cm4gbmV3IHRoaXMoeCkubG9nKDEwKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG1heGltdW0gb2YgdGhlIGFyZ3VtZW50cy4NCiAgICoNCiAgICogYXJndW1lbnRzIHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gbWF4KCkgew0KICAgIHJldHVybiBtYXhPck1pbih0aGlzLCBhcmd1bWVudHMsIC0xKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIG1pbmltdW0gb2YgdGhlIGFyZ3VtZW50cy4NCiAgICoNCiAgICogYXJndW1lbnRzIHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gbWluKCkgew0KICAgIHJldHVybiBtYXhPck1pbih0aGlzLCBhcmd1bWVudHMsIDEpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyBgeGAgbW9kdWxvIGB5YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYCBzaWduaWZpY2FudCBkaWdpdHMNCiAgICogdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKiB5IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gbW9kKHgsIHkpIHsNCiAgICByZXR1cm4gbmV3IHRoaXMoeCkubW9kKHkpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyBgeGAgbXVsdGlwbGllZCBieSBgeWAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmAgc2lnbmlmaWNhbnQNCiAgICogZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICogeSB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0NCiAgICoNCiAgICovDQogIGZ1bmN0aW9uIG11bCh4LCB5KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLm11bCh5KTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgYHhgIHJhaXNlZCB0byB0aGUgcG93ZXIgYHlgLCByb3VuZGVkIHRvIHByZWNpc2lvbg0KICAgKiBzaWduaWZpY2FudCBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBUaGUgYmFzZS4NCiAgICogeSB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gVGhlIGV4cG9uZW50Lg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gcG93KHgsIHkpIHsNCiAgICByZXR1cm4gbmV3IHRoaXMoeCkucG93KHkpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm5zIGEgbmV3IERlY2ltYWwgd2l0aCBhIHJhbmRvbSB2YWx1ZSBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gMCBhbmQgbGVzcyB0aGFuIDEsIGFuZCB3aXRoDQogICAqIGBzZGAsIG9yIGBEZWNpbWFsLnByZWNpc2lvbmAgaWYgYHNkYCBpcyBvbWl0dGVkLCBzaWduaWZpY2FudCBkaWdpdHMgKG9yIGxlc3MgaWYgdHJhaWxpbmcgemVyb3MNCiAgICogYXJlIHByb2R1Y2VkKS4NCiAgICoNCiAgICogW3NkXSB7bnVtYmVyfSBTaWduaWZpY2FudCBkaWdpdHMuIEludGVnZXIsIDAgdG8gTUFYX0RJR0lUUyBpbmNsdXNpdmUuDQogICAqDQogICAqLw0KICBmdW5jdGlvbiByYW5kb20oc2QpIHsNCiAgICB2YXIgZCwgZSwgaywgbiwNCiAgICAgIGkgPSAwLA0KICAgICAgciA9IG5ldyB0aGlzKDEpLA0KICAgICAgcmQgPSBbXTsNCg0KICAgIGlmIChzZCA9PT0gdm9pZCAwKSBzZCA9IHRoaXMucHJlY2lzaW9uOw0KICAgIGVsc2UgY2hlY2tJbnQzMihzZCwgMSwgTUFYX0RJR0lUUyk7DQoNCiAgICBrID0gTWF0aC5jZWlsKHNkIC8gTE9HX0JBU0UpOw0KDQogICAgaWYgKCF0aGlzLmNyeXB0bykgew0KICAgICAgZm9yICg7IGkgPCBrOykgcmRbaSsrXSA9IE1hdGgucmFuZG9tKCkgKiAxZTcgfCAwOw0KDQogICAgLy8gQnJvd3NlcnMgc3VwcG9ydGluZyBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLg0KICAgIH0gZWxzZSBpZiAoY3J5cHRvLmdldFJhbmRvbVZhbHVlcykgew0KICAgICAgZCA9IGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQzMkFycmF5KGspKTsNCg0KICAgICAgZm9yICg7IGkgPCBrOykgew0KICAgICAgICBuID0gZFtpXTsNCg0KICAgICAgICAvLyAwIDw9IG4gPCA0Mjk0OTY3Mjk2DQogICAgICAgIC8vIFByb2JhYmlsaXR5IG4gPj0gNC4yOWU5LCBpcyA0OTY3Mjk2IC8gNDI5NDk2NzI5NiA9IDAuMDAxMTYgKDEgaW4gODY1KS4NCiAgICAgICAgaWYgKG4gPj0gNC4yOWU5KSB7DQogICAgICAgICAgZFtpXSA9IGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQzMkFycmF5KDEpKVswXTsNCiAgICAgICAgfSBlbHNlIHsNCg0KICAgICAgICAgIC8vIDAgPD0gbiA8PSA0Mjg5OTk5OTk5DQogICAgICAgICAgLy8gMCA8PSAobiAlIDFlNykgPD0gOTk5OTk5OQ0KICAgICAgICAgIHJkW2krK10gPSBuICUgMWU3Ow0KICAgICAgICB9DQogICAgICB9DQoNCiAgICAvLyBOb2RlLmpzIHN1cHBvcnRpbmcgY3J5cHRvLnJhbmRvbUJ5dGVzLg0KICAgIH0gZWxzZSBpZiAoY3J5cHRvLnJhbmRvbUJ5dGVzKSB7DQoNCiAgICAgIC8vIGJ1ZmZlcg0KICAgICAgZCA9IGNyeXB0by5yYW5kb21CeXRlcyhrICo9IDQpOw0KDQogICAgICBmb3IgKDsgaSA8IGs7KSB7DQoNCiAgICAgICAgLy8gMCA8PSBuIDwgMjE0NzQ4MzY0OA0KICAgICAgICBuID0gZFtpXSArIChkW2kgKyAxXSA8PCA4KSArIChkW2kgKyAyXSA8PCAxNikgKyAoKGRbaSArIDNdICYgMHg3ZikgPDwgMjQpOw0KDQogICAgICAgIC8vIFByb2JhYmlsaXR5IG4gPj0gMi4xNGU5LCBpcyA3NDgzNjQ4IC8gMjE0NzQ4MzY0OCA9IDAuMDAzNSAoMSBpbiAyODYpLg0KICAgICAgICBpZiAobiA+PSAyLjE0ZTkpIHsNCiAgICAgICAgICBjcnlwdG8ucmFuZG9tQnl0ZXMoNCkuY29weShkLCBpKTsNCiAgICAgICAgfSBlbHNlIHsNCg0KICAgICAgICAgIC8vIDAgPD0gbiA8PSAyMTM5OTk5OTk5DQogICAgICAgICAgLy8gMCA8PSAobiAlIDFlNykgPD0gOTk5OTk5OQ0KICAgICAgICAgIHJkLnB1c2gobiAlIDFlNyk7DQogICAgICAgICAgaSArPSA0Ow0KICAgICAgICB9DQogICAgICB9DQoNCiAgICAgIGkgPSBrIC8gNDsNCiAgICB9IGVsc2Ugew0KICAgICAgdGhyb3cgRXJyb3IoY3J5cHRvVW5hdmFpbGFibGUpOw0KICAgIH0NCg0KICAgIGsgPSByZFstLWldOw0KICAgIHNkICU9IExPR19CQVNFOw0KDQogICAgLy8gQ29udmVydCB0cmFpbGluZyBkaWdpdHMgdG8gemVyb3MgYWNjb3JkaW5nIHRvIHNkLg0KICAgIGlmIChrICYmIHNkKSB7DQogICAgICBuID0gbWF0aHBvdygxMCwgTE9HX0JBU0UgLSBzZCk7DQogICAgICByZFtpXSA9IChrIC8gbiB8IDApICogbjsNCiAgICB9DQoNCiAgICAvLyBSZW1vdmUgdHJhaWxpbmcgd29yZHMgd2hpY2ggYXJlIHplcm8uDQogICAgZm9yICg7IHJkW2ldID09PSAwOyBpLS0pIHJkLnBvcCgpOw0KDQogICAgLy8gWmVybz8NCiAgICBpZiAoaSA8IDApIHsNCiAgICAgIGUgPSAwOw0KICAgICAgcmQgPSBbMF07DQogICAgfSBlbHNlIHsNCiAgICAgIGUgPSAtMTsNCg0KICAgICAgLy8gUmVtb3ZlIGxlYWRpbmcgd29yZHMgd2hpY2ggYXJlIHplcm8gYW5kIGFkanVzdCBleHBvbmVudCBhY2NvcmRpbmdseS4NCiAgICAgIGZvciAoOyByZFswXSA9PT0gMDsgZSAtPSBMT0dfQkFTRSkgcmQuc2hpZnQoKTsNCg0KICAgICAgLy8gQ291bnQgdGhlIGRpZ2l0cyBvZiB0aGUgZmlyc3Qgd29yZCBvZiByZCB0byBkZXRlcm1pbmUgbGVhZGluZyB6ZXJvcy4NCiAgICAgIGZvciAoayA9IDEsIG4gPSByZFswXTsgbiA+PSAxMDsgbiAvPSAxMCkgaysrOw0KDQogICAgICAvLyBBZGp1c3QgdGhlIGV4cG9uZW50IGZvciBsZWFkaW5nIHplcm9zIG9mIHRoZSBmaXJzdCB3b3JkIG9mIHJkLg0KICAgICAgaWYgKGsgPCBMT0dfQkFTRSkgZSAtPSBMT0dfQkFTRSAtIGs7DQogICAgfQ0KDQogICAgci5lID0gZTsNCiAgICByLmQgPSByZDsNCg0KICAgIHJldHVybiByOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyBgeGAgcm91bmRlZCB0byBhbiBpbnRlZ2VyIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogVG8gZW11bGF0ZSBgTWF0aC5yb3VuZGAsIHNldCByb3VuZGluZyB0byA3IChST1VORF9IQUxGX0NFSUwpLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gcm91bmQoeCkgew0KICAgIHJldHVybiBmaW5hbGlzZSh4ID0gbmV3IHRoaXMoeCksIHguZSArIDEsIHRoaXMucm91bmRpbmcpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4NCiAgICogICAxICAgIGlmIHggPiAwLA0KICAgKiAgLTEgICAgaWYgeCA8IDAsDQogICAqICAgMCAgICBpZiB4IGlzIDAsDQogICAqICAtMCAgICBpZiB4IGlzIC0wLA0KICAgKiAgIE5hTiAgb3RoZXJ3aXNlDQogICAqDQogICAqIHgge251bWJlcnxzdHJpbmd8YmlnaW50fERlY2ltYWx9DQogICAqDQogICAqLw0KICBmdW5jdGlvbiBzaWduKHgpIHsNCiAgICB4ID0gbmV3IHRoaXMoeCk7DQogICAgcmV0dXJuIHguZCA/ICh4LmRbMF0gPyB4LnMgOiAwICogeC5zKSA6IHgucyB8fCBOYU47DQogIH0NCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSBzaW5lIG9mIGB4YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYCBzaWduaWZpY2FudCBkaWdpdHMNCiAgICogdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBBIHZhbHVlIGluIHJhZGlhbnMuDQogICAqDQogICAqLw0KICBmdW5jdGlvbiBzaW4oeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS5zaW4oKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGh5cGVyYm9saWMgc2luZSBvZiBgeGAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gQSB2YWx1ZSBpbiByYWRpYW5zLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gc2luaCh4KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLnNpbmgoKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIHNxdWFyZSByb290IG9mIGB4YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYCBzaWduaWZpY2FudA0KICAgKiBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gc3FydCh4KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLnNxcnQoKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgYHhgIG1pbnVzIGB5YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYCBzaWduaWZpY2FudCBkaWdpdHMNCiAgICogdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKiB5IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gc3ViKHgsIHkpIHsNCiAgICByZXR1cm4gbmV3IHRoaXMoeCkuc3ViKHkpOw0KICB9DQoNCg0KICAvKg0KICAgKiBSZXR1cm4gYSBuZXcgRGVjaW1hbCB3aG9zZSB2YWx1ZSBpcyB0aGUgc3VtIG9mIHRoZSBhcmd1bWVudHMsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogT25seSB0aGUgcmVzdWx0IGlzIHJvdW5kZWQsIG5vdCB0aGUgaW50ZXJtZWRpYXRlIGNhbGN1bGF0aW9ucy4NCiAgICoNCiAgICogYXJndW1lbnRzIHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gc3VtKCkgew0KICAgIHZhciBpID0gMCwNCiAgICAgIGFyZ3MgPSBhcmd1bWVudHMsDQogICAgICB4ID0gbmV3IHRoaXMoYXJnc1tpXSk7DQoNCiAgICBleHRlcm5hbCA9IGZhbHNlOw0KICAgIGZvciAoOyB4LnMgJiYgKytpIDwgYXJncy5sZW5ndGg7KSB4ID0geC5wbHVzKGFyZ3NbaV0pOw0KICAgIGV4dGVybmFsID0gdHJ1ZTsNCg0KICAgIHJldHVybiBmaW5hbGlzZSh4LCB0aGlzLnByZWNpc2lvbiwgdGhpcy5yb3VuZGluZyk7DQogIH0NCg0KDQogIC8qDQogICAqIFJldHVybiBhIG5ldyBEZWNpbWFsIHdob3NlIHZhbHVlIGlzIHRoZSB0YW5nZW50IG9mIGB4YCwgcm91bmRlZCB0byBgcHJlY2lzaW9uYCBzaWduaWZpY2FudA0KICAgKiBkaWdpdHMgdXNpbmcgcm91bmRpbmcgbW9kZSBgcm91bmRpbmdgLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfSBBIHZhbHVlIGluIHJhZGlhbnMuDQogICAqDQogICAqLw0KICBmdW5jdGlvbiB0YW4oeCkgew0KICAgIHJldHVybiBuZXcgdGhpcyh4KS50YW4oKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgdGhlIGh5cGVyYm9saWMgdGFuZ2VudCBvZiBgeGAsIHJvdW5kZWQgdG8gYHByZWNpc2lvbmANCiAgICogc2lnbmlmaWNhbnQgZGlnaXRzIHVzaW5nIHJvdW5kaW5nIG1vZGUgYHJvdW5kaW5nYC4NCiAgICoNCiAgICogeCB7bnVtYmVyfHN0cmluZ3xiaWdpbnR8RGVjaW1hbH0gQSB2YWx1ZSBpbiByYWRpYW5zLg0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gdGFuaCh4KSB7DQogICAgcmV0dXJuIG5ldyB0aGlzKHgpLnRhbmgoKTsNCiAgfQ0KDQoNCiAgLyoNCiAgICogUmV0dXJuIGEgbmV3IERlY2ltYWwgd2hvc2UgdmFsdWUgaXMgYHhgIHRydW5jYXRlZCB0byBhbiBpbnRlZ2VyLg0KICAgKg0KICAgKiB4IHtudW1iZXJ8c3RyaW5nfGJpZ2ludHxEZWNpbWFsfQ0KICAgKg0KICAgKi8NCiAgZnVuY3Rpb24gdHJ1bmMoeCkgew0KICAgIHJldHVybiBmaW5hbGlzZSh4ID0gbmV3IHRoaXMoeCksIHguZSArIDEsIDEpOw0KICB9DQoNCg0KICBQW1N5bWJvbC5mb3IoJ25vZGVqcy51dGlsLmluc3BlY3QuY3VzdG9tJyldID0gUC50b1N0cmluZzsNCiAgUFtTeW1ib2wudG9TdHJpbmdUYWddID0gJ0RlY2ltYWwnOw0KDQogIC8vIENyZWF0ZSBhbmQgY29uZmlndXJlIGluaXRpYWwgRGVjaW1hbCBjb25zdHJ1Y3Rvci4NCiAgdmFyIERlY2ltYWwgPSBQLmNvbnN0cnVjdG9yID0gY2xvbmUoREVGQVVMVFMpOw0KDQogIC8vIENyZWF0ZSB0aGUgaW50ZXJuYWwgY29uc3RhbnRzIGZyb20gdGhlaXIgc3RyaW5nIHZhbHVlcy4NCiAgTE4xMCA9IG5ldyBEZWNpbWFsKExOMTApOw0KICBQSSA9IG5ldyBEZWNpbWFsKFBJKTsKCiAgLyoqCiAgICog6I635Y+W5Lmw5LiALOWPoOWKoOeCueW3rgogICAqIEJpZCA9IEJpZCAtIChTcHJlYWQgLyAyICogMTBeLWRpZ2l0cykKICAgKi8KICB2YXIgZ2V0TVQ1UmVhbEJpZE9uZSA9IGZ1bmN0aW9uIGdldE1UNVJlYWxCaWRPbmUoKSB7CiAgICB2YXIgYmlkMSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogMDsKICAgIHZhciBzcHJlYWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7CiAgICB2YXIgZGlnaXRzID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAwOwogICAgaWYgKG5ldyBEZWNpbWFsKHNwcmVhZCkuZXEoMCkpIHsKICAgICAgcmV0dXJuIGJpZDE7CiAgICB9CiAgICB2YXIgcmVhbEJpZDEgPSBuZXcgRGVjaW1hbChiaWQxKS5taW51cyhuZXcgRGVjaW1hbChzcHJlYWQpLmRpdigyKS5tdWwobmV3IERlY2ltYWwoMTApLnBvdygtZGlnaXRzKSkpLnRvU3RyaW5nKCk7CiAgICByZXR1cm4gcmVhbEJpZDE7CiAgfTsKICAvKioKICAgKiDojrflj5bljZbkuIDvvIzlj6DliqDngrnlt64KICAgKiBBc2sgPSBBc2sgKyAoU3ByZWFkIC8gMiAqIDEwXi1kaWdpdHMpCiAgICovCiAgdmFyIGdldE1UNVJlYWxBc2tPbmUgPSBmdW5jdGlvbiBnZXRNVDVSZWFsQXNrT25lKCkgewogICAgdmFyIGFzazEgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IDA7CiAgICB2YXIgc3ByZWFkID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAwOwogICAgdmFyIGRpZ2l0cyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogMDsKICAgIGlmIChuZXcgRGVjaW1hbChzcHJlYWQpLmVxKDApKSB7CiAgICAgIHJldHVybiBhc2sxOwogICAgfQogICAgdmFyIHJlYWxBc2sxID0gbmV3IERlY2ltYWwoYXNrMSkucGx1cyhuZXcgRGVjaW1hbChzcHJlYWQpLmRpdigyKS5tdWwobmV3IERlY2ltYWwoMTApLnBvdygtZGlnaXRzKSkpLnRvU3RyaW5nKCk7CiAgICByZXR1cm4gcmVhbEFzazE7CiAgfTsKICAvKioKICAgKiDojrflj5bkubDkuIDljZbkuIDngrnlt64KICAgKiAoYXNrMSAtIGJpZDEpICogcG93KDEwLGRpZ2l0cykKICAgKi8KICB2YXIgZ2V0TVQ1QXNrQmlkU3ByZWFkID0gZnVuY3Rpb24gZ2V0TVQ1QXNrQmlkU3ByZWFkKCkgewogICAgdmFyIHJlYWxBc2sxID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAwOwogICAgdmFyIHJlYWxCaWQxID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAwOwogICAgdmFyIGRpZ2l0cyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogMDsKICAgIHZhciBzcHJlYWQgPSBuZXcgRGVjaW1hbChyZWFsQXNrMSkubWludXMobmV3IERlY2ltYWwocmVhbEJpZDEpKS5tdWwobmV3IERlY2ltYWwoMTApLnBvdyhkaWdpdHMpKTsKICAgIHJldHVybiBzcHJlYWQudG9EZWNpbWFsUGxhY2VzKDAsIERlY2ltYWwuUk9VTkRfRkxPT1IpLnRvU3RyaW5nKCk7CiAgfTsKICB2YXIgZ2V0VmFsaWRWYWwgPSBmdW5jdGlvbiBnZXRWYWxpZFZhbCh2YWwsIG9yaWdpblZhbCkgewogICAgcmV0dXJuIHZhbCA9PT0gdW5kZWZpbmVkID8gb3JpZ2luVmFsIDogdmFsOwogIH07CgogIC8vIEFzc3VtaW5nIHRoaXMgaXMgeW91ciB3ZWVrZGF5IG1hcHBpbmcKICB2YXIgd2Vla0RheU1hcCA9IHsKICAgIE1vbjogMSwKICAgIFR1ZXM6IDIsCiAgICBXZWQ6IDMsCiAgICBUaHVyOiA0LAogICAgRnJpOiA1LAogICAgU2F0OiA2LAogICAgU3VuOiA3CiAgfTsKICB2YXIgcGFyc2VSYW5nZXMgPSBmdW5jdGlvbiBwYXJzZVJhbmdlcyhyYW5nZXMpIHsKICAgIHJldHVybiByYW5nZXMubWFwKGZ1bmN0aW9uIChyKSB7CiAgICAgIHZhciBwYXJ0cyA9IHIuc3BsaXQoJy0nKTsKICAgICAgdmFyIHNwID0gcGFydHNbMF0uc3BsaXQoJzonKS5tYXAoTnVtYmVyKTsKICAgICAgdmFyIGVwID0gcGFydHNbMV0uc3BsaXQoJzonKS5tYXAoTnVtYmVyKTsKICAgICAgdmFyIHN0YXJ0ID0gc3BbMF0gKiAzNjAwICsgc3BbMV0gKiA2MDsKICAgICAgdmFyIGVuZCA9IGVwWzBdICogMzYwMCArIGVwWzFdICogNjA7CiAgICAgIC8vIENyb3NzLWRheSBjb25maWd1cmF0aW9uCiAgICAgIGlmIChlbmQgPD0gc3RhcnQpIHsKICAgICAgICBlbmQgKz0gMjQgKiAzNjAwOwogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICAgIGVuZDogZW5kCiAgICAgIH07CiAgICB9KTsKICB9OwogIHZhciBjaGVjayA9IGZ1bmN0aW9uIGNoZWNrKHNlcnZlclRpbWVNcywgc2Vzc2lvbnMpIHsKICAgIHZhciBfT2JqZWN0JGVudHJpZXMkZmluZDsKICAgIC8vIGNvbnNvbGUubG9nKCdzZXJ2ZXJUaW1lIE9yaWdpbjonICsgc2VydmVyVGltZU1zKTsKICAgIHZhciBzZXJ2ZXJMb2NhbCA9IG5ldyBEYXRlKHNlcnZlclRpbWVNcyk7CiAgICAvLyBjb25zb2xlLmxvZygnc2VydmVyTG9jYWw6JyArIHNlcnZlckxvY2FsKTsKICAgIC8vIFRPRE86IGNoZWNrIEphdmFTY3JpcHQgZ2V0RGF5KCkgcmV0dXJucyAwIGZvciBTdW5kYXksIHdlIG5lZWQgdG8gYWRqdXN0IHRvIG1hdGNoIERhcnQncyB3ZWVrZGF5ICgxLTcpCiAgICB2YXIgd2Vla2RheSA9IHNlcnZlckxvY2FsLmdldFVUQ0RheSgpOwogICAgaWYgKHdlZWtkYXkgPT09IDApIHdlZWtkYXkgPSA3OwogICAgLy8gY29uc29sZS5sb2coJ3dlZWtkYXk6JyArIHdlZWtkYXkpOwogICAgdmFyIGRheU5hbWUgPSAoX09iamVjdCRlbnRyaWVzJGZpbmQgPSBPYmplY3QuZW50cmllcyh3ZWVrRGF5TWFwKS5maW5kKGZ1bmN0aW9uIChfcmVmKSB7CiAgICAgIHZhciBfcmVmMiA9IF9zbGljZWRUb0FycmF5KF9yZWYsIDIpOwogICAgICAgIF9yZWYyWzBdOwogICAgICAgIHZhciB2YWx1ZSA9IF9yZWYyWzFdOwogICAgICByZXR1cm4gdmFsdWUgPT09IHdlZWtkYXk7CiAgICB9KSkgPT09IG51bGwgfHwgX09iamVjdCRlbnRyaWVzJGZpbmQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9PYmplY3QkZW50cmllcyRmaW5kWzBdOwogICAgLy8gY29uc29sZS5sb2coJ2RheU5hbWU6JyArIGRheU5hbWUpOwogICAgaWYgKCFkYXlOYW1lKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgdmFyIHRvZGF5ID0gc2Vzc2lvbnMuZmluZChmdW5jdGlvbiAoZCkgewogICAgICByZXR1cm4gZC5kYXkgPT09IGRheU5hbWU7CiAgICB9KTsKICAgIC8vIGNvbnNvbGUubG9nKCd0b2RheTonLCB0b2RheSk7CiAgICBpZiAoIXRvZGF5KSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgdmFyIHBlcmlvZHMgPSBfdG9Db25zdW1hYmxlQXJyYXkodG9kYXkudHJhZGVTZXNzaW9ucyk7CiAgICB2YXIgY3VycmVudFNlY29uZHMgPSBzZXJ2ZXJMb2NhbC5nZXRVVENIb3VycygpICogMzYwMCArIHNlcnZlckxvY2FsLmdldFVUQ01pbnV0ZXMoKSAqIDYwICsgc2VydmVyTG9jYWwuZ2V0VVRDU2Vjb25kcygpOwogICAgLy8gY29uc29sZS5sb2coJ3NlcnZlckxvY2FsLmdldFVUQ0hvdXJzKCkgKiAzNjAwOicsIHNlcnZlckxvY2FsLmdldFVUQ0hvdXJzKCksIHNlcnZlckxvY2FsLmdldFVUQ01pbnV0ZXMoKSwgc2VydmVyTG9jYWwuZ2V0VVRDU2Vjb25kcygpKTsKICAgIC8vIGNvbnNvbGUubG9nKCdjdXJyZW50U2Vjb25kczonLCBjdXJyZW50U2Vjb25kcyk7CiAgICB2YXIgdG9kYXlSYW5nZXMgPSBwYXJzZVJhbmdlcyhwZXJpb2RzKTsKICAgIC8vIGNvbnNvbGUubG9nKCd0b2RheVJhbmdlczonLCB0b2RheVJhbmdlcyk7CiAgICAvLyBDaGVjayBpZiB3aXRoaW4gdG9kYXkncyB0aW1lIHJhbmdlcwogICAgdmFyIF9pdGVyYXRvciA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyKHRvZGF5UmFuZ2VzKSwKICAgICAgX3N0ZXA7CiAgICB0cnkgewogICAgICBmb3IgKF9pdGVyYXRvci5zKCk7ICEoX3N0ZXAgPSBfaXRlcmF0b3IubigpKS5kb25lOykgewogICAgICAgIHZhciByID0gX3N0ZXAudmFsdWU7CiAgICAgICAgaWYgKGN1cnJlbnRTZWNvbmRzID49IHIuc3RhcnQgJiYgY3VycmVudFNlY29uZHMgPCByLmVuZCkgewogICAgICAgICAgLy8gY29uc29sZS5sb2coJ2luIHRvZGF5OicgKyAoci5lbmQgLSBjdXJyZW50U2Vjb25kcykpOwogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgaXNJblRyYWRlVGltZTogdHJ1ZSwKICAgICAgICAgICAgZW5kVGltZTogci5lbmQgLSBjdXJyZW50U2Vjb25kcwogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLy8gQ2hlY2sgaWYgYmVmb3JlIHRvZGF5J3MgbmV4dCB0aW1lIHJhbmdlCiAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgX2l0ZXJhdG9yLmUoZXJyKTsKICAgIH0gZmluYWxseSB7CiAgICAgIF9pdGVyYXRvci5mKCk7CiAgICB9CiAgICB2YXIgX2l0ZXJhdG9yMiA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyKHRvZGF5UmFuZ2VzKSwKICAgICAgX3N0ZXAyOwogICAgdHJ5IHsKICAgICAgZm9yIChfaXRlcmF0b3IyLnMoKTsgIShfc3RlcDIgPSBfaXRlcmF0b3IyLm4oKSkuZG9uZTspIHsKICAgICAgICB2YXIgX3IgPSBfc3RlcDIudmFsdWU7CiAgICAgICAgaWYgKGN1cnJlbnRTZWNvbmRzIDwgX3Iuc3RhcnQpIHsKICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCduZXh0IHJhbmdlIHRvZGF5OicgKyAoci5zdGFydCAtIGN1cnJlbnRTZWNvbmRzKSk7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICBpc0luVHJhZGVUaW1lOiBmYWxzZSwKICAgICAgICAgICAgc3RhcnRUaW1lOiBfci5zdGFydCAtIGN1cnJlbnRTZWNvbmRzCiAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgfQogICAgICAvLyBGaW5kIHRoZSBuZXh0IHRyYWRhYmxlIGRheQogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIF9pdGVyYXRvcjIuZShlcnIpOwogICAgfSBmaW5hbGx5IHsKICAgICAgX2l0ZXJhdG9yMi5mKCk7CiAgICB9CiAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcCgpIHsKICAgICAgICB2YXIgX09iamVjdCRlbnRyaWVzJGZpbmQyOwogICAgICAgIHZhciBuZXh0RGF5ID0gKHdlZWtkYXkgKyBvZmZzZXQgLSAxKSAlIDcgKyAxOwogICAgICAgIHZhciBuZXh0TmFtZSA9IChfT2JqZWN0JGVudHJpZXMkZmluZDIgPSBPYmplY3QuZW50cmllcyh3ZWVrRGF5TWFwKS5maW5kKGZ1bmN0aW9uIChfcmVmMykgewogICAgICAgICAgdmFyIF9yZWY0ID0gX3NsaWNlZFRvQXJyYXkoX3JlZjMsIDIpOwogICAgICAgICAgICBfcmVmNFswXTsKICAgICAgICAgICAgdmFyIHZhbHVlID0gX3JlZjRbMV07CiAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IG5leHREYXk7CiAgICAgICAgfSkpID09PSBudWxsIHx8IF9PYmplY3QkZW50cmllcyRmaW5kMiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX09iamVjdCRlbnRyaWVzJGZpbmQyWzBdOwogICAgICAgIC8vIGNvbnNvbGUubG9nKCduZXh0TmFtZTonICsgbmV4dE5hbWUpOwogICAgICAgIGlmICghbmV4dE5hbWUpIHsKICAgICAgICAgIHJldHVybiAwOyAvLyBjb250aW51ZQogICAgICAgIH0KICAgICAgICAvLyBjb25zb2xlLmxvZygnbmV4dERheTonICsgbmV4dERheSk7CiAgICAgICAgdmFyIGRzID0gc2Vzc2lvbnMuZmluZChmdW5jdGlvbiAoZCkgewogICAgICAgICAgcmV0dXJuIGQuZGF5ID09PSBuZXh0TmFtZTsKICAgICAgICB9KTsKICAgICAgICBpZiAoIWRzKSB7CiAgICAgICAgICByZXR1cm4gMDsgLy8gY29udGludWUKICAgICAgICB9CiAgICAgICAgdmFyIG5leHRQZXJpb2RzID0gX3RvQ29uc3VtYWJsZUFycmF5KGRzLnRyYWRlU2Vzc2lvbnMpOwogICAgICAgIHZhciBuZXh0UmFuZ2VzID0gcGFyc2VSYW5nZXMobmV4dFBlcmlvZHMpOwogICAgICAgIC8vIGNvbnNvbGUubG9nKCduZXh0UmFuZ2VzOicsIG5leHRSYW5nZXMpOwogICAgICAgIGlmIChuZXh0UmFuZ2VzLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHZhciBzdGFydCA9IG5leHRSYW5nZXNbMF0uc3RhcnQgKyBvZmZzZXQgKiAyNCAqIDM2MDA7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICB2OiB7CiAgICAgICAgICAgICAgaXNJblRyYWRlVGltZTogZmFsc2UsCiAgICAgICAgICAgICAgc3RhcnRUaW1lOiBzdGFydCAtIChzZXJ2ZXJMb2NhbC5nZXRVVENIb3VycygpICogMzYwMCArIHNlcnZlckxvY2FsLmdldFVUQ01pbnV0ZXMoKSAqIDYwICsgc2VydmVyTG9jYWwuZ2V0VVRDU2Vjb25kcygpKQogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgfSwKICAgICAgX3JldDsKICAgIGZvciAodmFyIG9mZnNldCA9IDE7IG9mZnNldCA8PSA3OyBvZmZzZXQrKykgewogICAgICBfcmV0ID0gX2xvb3AoKTsKICAgICAgaWYgKF9yZXQgPT09IDApIGNvbnRpbnVlOwogICAgICBpZiAoX3JldCkgcmV0dXJuIF9yZXQudjsKICAgIH0KICAgIC8vIENvbmZpZ3VyYXRpb24gZXJyb3IsIG5vIHRyYWRpbmcgZGF5cyBmb3VuZAogICAgcmV0dXJuIG51bGw7CiAgfTsKICB2YXIgZ2V0U3ltYm9sU2Vzc2lvblRyYWRlQ2hlY2sgPSBmdW5jdGlvbiBnZXRTeW1ib2xTZXNzaW9uVHJhZGVDaGVjayhzZXJ2ZXJUaW1lLCBsYXN0UmVxU2VydmVyVGltZSwgc2Vzc2lvbnMpIHsKICAgIHZhciBzZXNzaW9uVHJhZGVDaGVjayA9IG51bGw7CiAgICBpZiAoc2VydmVyVGltZSAmJiBzZXJ2ZXJUaW1lICE9PSAnJykgewogICAgICB2YXIgc2VydmVyVGltZU1TID0gTnVtYmVyKHNlcnZlclRpbWUpIHx8IDA7CiAgICAgIC8vIGNvbnN0IGFjY291bnRUaW1lWm9uZSA9dHJhZGZpSW5mbz8uc2VydmVyVGltZVpvbmU7CiAgICAgIGlmIChzZXJ2ZXJUaW1lTVMgPiAwKSB7CiAgICAgICAgLy8gQWRkIGxvY2FsIHJlbGF0aXZlIHRpbWUgKDFzdCBzaG91bGQgYmUgc21hbGwgZGlmZikKICAgICAgICB2YXIgb2Zmc2V0VGltZSA9IDA7CiAgICAgICAgdmFyIGxhc3RTZXJ2ZXJUaW1lID0gTnVtYmVyKGxhc3RSZXFTZXJ2ZXJUaW1lKSB8fCAwOwogICAgICAgIGlmIChsYXN0U2VydmVyVGltZSA+IDApIHsKICAgICAgICAgIG9mZnNldFRpbWUgPSBEYXRlLm5vdygpIC0gbGFzdFNlcnZlclRpbWU7CiAgICAgICAgfQogICAgICAgIHNlc3Npb25UcmFkZUNoZWNrID0gY2hlY2soc2VydmVyVGltZU1TICsgb2Zmc2V0VGltZSwgc2Vzc2lvbnMpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gc2Vzc2lvblRyYWRlQ2hlY2s7CiAgfTsKICB2YXIgbXQ1VGlja2Vyc0FsbEZuID0gZnVuY3Rpb24gbXQ1VGlja2Vyc0FsbEZuKGRhdGEsIG10NVRpY2tlcnNBbGxQYXJhbXMsIG10NVRpY2tlcnNBbGxNYXApIHsKICAgIHZhciByZXN1bHQgPSBkYXRhLm1hcChmdW5jdGlvbiAoaXRlbSkgewogICAgICB2YXIgX3JlZjUgPSBtdDVUaWNrZXJzQWxsUGFyYW1zIHx8IHsKICAgICAgICAgIGFsbFN5bWJvbENvbmZpZzoge30KICAgICAgICB9LAogICAgICAgIF9yZWY1JGFsbFN5bWJvbENvbmZpZyA9IF9yZWY1LmFsbFN5bWJvbENvbmZpZywKICAgICAgICBhbGxTeW1ib2xDb25maWcgPSBfcmVmNSRhbGxTeW1ib2xDb25maWcgPT09IHZvaWQgMCA/IHt9IDogX3JlZjUkYWxsU3ltYm9sQ29uZmlnOwogICAgICB2YXIgX3JlZjYgPSAoYWxsU3ltYm9sQ29uZmlnID09PSBudWxsIHx8IGFsbFN5bWJvbENvbmZpZyA9PT0gdm9pZCAwID8gdm9pZCAwIDogYWxsU3ltYm9sQ29uZmlnW2l0ZW0uc10pIHx8IHsKICAgICAgICAgIHNwcmVhZDogMCwKICAgICAgICAgIGRpZ2l0czogMAogICAgICAgIH0sCiAgICAgICAgX3JlZjYkc3ByZWFkID0gX3JlZjYuc3ByZWFkLAogICAgICAgIHNwcmVhZCA9IF9yZWY2JHNwcmVhZCA9PT0gdm9pZCAwID8gMCA6IF9yZWY2JHNwcmVhZCwKICAgICAgICBfcmVmNiRkaWdpdHMgPSBfcmVmNi5kaWdpdHMsCiAgICAgICAgZGlnaXRzID0gX3JlZjYkZGlnaXRzID09PSB2b2lkIDAgPyAwIDogX3JlZjYkZGlnaXRzOwogICAgICB2YXIgX3JlZjcgPSAobXQ1VGlja2Vyc0FsbE1hcCA9PT0gbnVsbCB8fCBtdDVUaWNrZXJzQWxsTWFwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBtdDVUaWNrZXJzQWxsTWFwW2l0ZW0uc10pIHx8IHt9LAogICAgICAgIF9yZWY3JG9yaWdpbkFzayA9IF9yZWY3Lm9yaWdpbkFzaywKICAgICAgICBvcmlnaW5Bc2sgPSBfcmVmNyRvcmlnaW5Bc2sgPT09IHZvaWQgMCA/IDAgOiBfcmVmNyRvcmlnaW5Bc2ssCiAgICAgICAgX3JlZjckb3JpZ2luQmlkID0gX3JlZjcub3JpZ2luQmlkLAogICAgICAgIG9yaWdpbkJpZCA9IF9yZWY3JG9yaWdpbkJpZCA9PT0gdm9pZCAwID8gMCA6IF9yZWY3JG9yaWdpbkJpZCwKICAgICAgICBfcmVmNyRzeW1ib2wgPSBfcmVmNy5zeW1ib2wsCiAgICAgICAgc3ltYm9sID0gX3JlZjckc3ltYm9sID09PSB2b2lkIDAgPyAnJyA6IF9yZWY3JHN5bWJvbCwKICAgICAgICBfcmVmNyR0aW1lID0gX3JlZjcudGltZSwKICAgICAgICB0aW1lID0gX3JlZjckdGltZSA9PT0gdm9pZCAwID8gJycgOiBfcmVmNyR0aW1lLAogICAgICAgIF9yZWY3JHRpbWVab25lID0gX3JlZjcudGltZVpvbmUsCiAgICAgICAgdGltZVpvbmUgPSBfcmVmNyR0aW1lWm9uZSA9PT0gdm9pZCAwID8gJycgOiBfcmVmNyR0aW1lWm9uZSwKICAgICAgICBfcmVmNyRjaGFuZ2UgPSBfcmVmNy5jaGFuZ2UsCiAgICAgICAgY2hhbmdlID0gX3JlZjckY2hhbmdlID09PSB2b2lkIDAgPyAnJyA6IF9yZWY3JGNoYW5nZSwKICAgICAgICBfcmVmNyRoaWdoID0gX3JlZjcuaGlnaDI0LAogICAgICAgIGhpZ2gyNCA9IF9yZWY3JGhpZ2ggPT09IHZvaWQgMCA/ICcnIDogX3JlZjckaGlnaCwKICAgICAgICBfcmVmNyRsb3cgPSBfcmVmNy5sb3cyNCwKICAgICAgICBsb3cyNCA9IF9yZWY3JGxvdyA9PT0gdm9pZCAwID8gJycgOiBfcmVmNyRsb3c7CiAgICAgIHZhciByZWFsQXNrMSA9IGdldE1UNVJlYWxBc2tPbmUoZ2V0VmFsaWRWYWwoaXRlbS5hLCBvcmlnaW5Bc2spLCBzcHJlYWQsIGRpZ2l0cyk7CiAgICAgIHZhciByZWFsQmlkMSA9IGdldE1UNVJlYWxCaWRPbmUoZ2V0VmFsaWRWYWwoaXRlbS5iLCBvcmlnaW5CaWQpLCBzcHJlYWQsIGRpZ2l0cyk7CiAgICAgIHJldHVybiB7CiAgICAgICAgb3JpZ2luQXNrOiBnZXRWYWxpZFZhbChpdGVtLmEsIG9yaWdpbkFzayksCiAgICAgICAgb3JpZ2luQmlkOiBnZXRWYWxpZFZhbChpdGVtLmIsIG9yaWdpbkJpZCksCiAgICAgICAgc3ltYm9sOiBnZXRWYWxpZFZhbChpdGVtLnMsIHN5bWJvbCksCiAgICAgICAgYXNrOiByZWFsQXNrMSwKICAgICAgICBiaWQ6IHJlYWxCaWQxLAogICAgICAgIHRpbWU6IGdldFZhbGlkVmFsKGl0ZW0udCwgdGltZSksCiAgICAgICAgdGltZVpvbmU6IGdldFZhbGlkVmFsKGl0ZW0ueiwgdGltZVpvbmUpLAogICAgICAgIGNoYW5nZTogZ2V0VmFsaWRWYWwoaXRlbS5jLCBjaGFuZ2UpLAogICAgICAgIGhpZ2gyNDogZ2V0VmFsaWRWYWwoaXRlbS5oLCBoaWdoMjQpLAogICAgICAgIGxvdzI0OiBnZXRWYWxpZFZhbChpdGVtLmwsIGxvdzI0KSwKICAgICAgICBzcHJlYWQ6IGdldE1UNUFza0JpZFNwcmVhZChyZWFsQXNrMSB8fCAwLCByZWFsQmlkMSB8fCAwLCBkaWdpdHMpCiAgICAgIH07CiAgICB9KS5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgaXRlbSkgewogICAgICBhY2NbaXRlbS5zeW1ib2xdID0gaXRlbTsKICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIHt9KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfTsKICB2YXIgZm9ybWF0TXQ1S2xpbmVGbiA9IGZ1bmN0aW9uIGZvcm1hdE10NUtsaW5lRm4oZGF0YSkgewogICAgdmFyIHRvcGljID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnJzsKICAgIHZhciBwdWJsaWNQYXJhbXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZDsKICAgIHZhciBfcmVmOCA9IHB1YmxpY1BhcmFtcyB8fCB7fSwKICAgICAgYWxsU3ltYm9sQ29uZmlnID0gX3JlZjguYWxsU3ltYm9sQ29uZmlnOwogICAgdmFyIHN5bWJvbCA9IHRvcGljLnNwbGl0KCcuJykucG9wKCkgfHwgJyc7CiAgICB2YXIgc3ltYm9sQ29uZmlnID0gYWxsU3ltYm9sQ29uZmlnID09PSBudWxsIHx8IGFsbFN5bWJvbENvbmZpZyA9PT0gdm9pZCAwID8gdm9pZCAwIDogYWxsU3ltYm9sQ29uZmlnW3N5bWJvbF07CiAgICB2YXIgX3JlZjkgPSBzeW1ib2xDb25maWcgIT09IG51bGwgJiYgc3ltYm9sQ29uZmlnICE9PSB2b2lkIDAgPyBzeW1ib2xDb25maWcgOiB7fSwKICAgICAgX3JlZjkkc3ByZWFkID0gX3JlZjkuc3ByZWFkLAogICAgICBzcHJlYWQgPSBfcmVmOSRzcHJlYWQgPT09IHZvaWQgMCA/IDAgOiBfcmVmOSRzcHJlYWQsCiAgICAgIF9yZWY5JGRpZ2l0cyA9IF9yZWY5LmRpZ2l0cywKICAgICAgZGlnaXRzID0gX3JlZjkkZGlnaXRzID09PSB2b2lkIDAgPyAwIDogX3JlZjkkZGlnaXRzOwogICAgaWYgKCFzeW1ib2xDb25maWcpIHJldHVybiBkYXRhOwogICAgcmV0dXJuIGRhdGEubWFwKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgIHJldHVybiBfb2JqZWN0U3ByZWFkMiQyKF9vYmplY3RTcHJlYWQyJDIoe30sIGl0ZW0pLCB7fSwgewogICAgICAgIG9wZW46IGdldE1UNVJlYWxCaWRPbmUoaXRlbS5vcGVuLCBzcHJlYWQsIGRpZ2l0cyksCiAgICAgICAgaGlnaDogZ2V0TVQ1UmVhbEJpZE9uZShpdGVtLmhpZ2gsIHNwcmVhZCwgZGlnaXRzKSwKICAgICAgICBsb3c6IGdldE1UNVJlYWxCaWRPbmUoaXRlbS5sb3csIHNwcmVhZCwgZGlnaXRzKSwKICAgICAgICBjbG9zZTogZ2V0TVQ1UmVhbEJpZE9uZShpdGVtLmNsb3NlLCBzcHJlYWQsIGRpZ2l0cykKICAgICAgfSk7CiAgICB9KTsKICB9OwoKICB2YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlOwogIHZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nOwogIHZhciBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJzsKICB2YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7CiAgdmFyIE5BTiA9IDAgLyAwOwogIHZhciBJTkZJTklUWSA9IDEgLyAwOwogIHZhciBNQVhfSU5URUdFUiA9IDEuNzk3NjkzMTM0ODYyMzE1N2UzMDg7CiAgLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4gKi8KICB2YXIgcmVUcmltID0gL15ccyt8XHMrJC9nOwogIC8qKiBVc2VkIHRvIGRldGVjdCBiYWQgc2lnbmVkIGhleGFkZWNpbWFsIHN0cmluZyB2YWx1ZXMuICovCiAgdmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTsKICAvKiogVXNlZCB0byBkZXRlY3QgYmluYXJ5IHN0cmluZyB2YWx1ZXMuICovCiAgdmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7CiAgLyoqIFVzZWQgdG8gZGV0ZWN0IG9jdGFsIHN0cmluZyB2YWx1ZXMuICovCiAgdmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7CiAgdmFyIGlzT2JqZWN0TGlrZSA9IGZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkgewogICAgcmV0dXJuICEhdmFsdWUgJiYgX3R5cGVvZiQxKHZhbHVlKSA9PT0gJ29iamVjdCc7CiAgfTsKICB2YXIgaXNOdW1iZXIgPSBmdW5jdGlvbiBpc051bWJlcih2YWx1ZSkgewogICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHwgaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBudW1iZXJUYWc7CiAgfTsKICB2YXIgaXNOYU4kMSA9IGZ1bmN0aW9uIGlzTmFOKHZhbHVlKSB7CiAgICByZXR1cm4gaXNOdW1iZXIodmFsdWUpICYmIHZhbHVlICE9ICt2YWx1ZTsKICB9OwogIHZhciBpc0Zpbml0ZSQxID0gZnVuY3Rpb24gaXNGaW5pdGUodmFsdWUpIHsKICAgIHJldHVybiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpOwogIH07CiAgdmFyIGlzT2JqZWN0ID0gZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHsKICAgIHZhciB0eXBlID0gX3R5cGVvZiQxKHZhbHVlKTsKICAgIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7CiAgfTsKICB2YXIgaXNTeW1ib2wgPSBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkgewogICAgcmV0dXJuIF90eXBlb2YkMSh2YWx1ZSkgPT09ICdzeW1ib2wnIHx8IGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3ltYm9sVGFnOwogIH07CiAgdmFyIGlzSW50ZWdlciA9IGZ1bmN0aW9uIGlzSW50ZWdlcih2YWx1ZSkgewogICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgdmFsdWUgPT0gdG9JbnRlZ2VyKHZhbHVlKTsKICB9OwogIHZhciB0b051bWJlciQxID0gZnVuY3Rpb24gdG9OdW1iZXIodmFsdWUpIHsKICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KICAgIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHsKICAgICAgcmV0dXJuIE5BTjsKICAgIH0KICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHsKICAgICAgdmFyIG90aGVyID0gdHlwZW9mIHZhbHVlLnZhbHVlT2YgPT09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTsKICAgICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAiIi5jb25jYXQob3RoZXIpIDogb3RoZXI7CiAgICB9CiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykgewogICAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6ICt2YWx1ZTsKICAgIH0KICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZVRyaW0sICcnKTsKICAgIHZhciBpc0JpbmFyeSA9IHJlSXNCaW5hcnkudGVzdCh2YWx1ZSk7CiAgICByZXR1cm4gaXNCaW5hcnkgfHwgcmVJc09jdGFsLnRlc3QodmFsdWUpID8gcGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpIDogcmVJc0JhZEhleC50ZXN0KHZhbHVlKSA/IE5BTiA6ICt2YWx1ZTsKICB9OwogIHZhciB0b0Zpbml0ZSA9IGZ1bmN0aW9uIHRvRmluaXRlKHZhbHVlKSB7CiAgICBpZiAoIXZhbHVlKSB7CiAgICAgIHJldHVybiB2YWx1ZSA9PT0gMCA/IHZhbHVlIDogMDsKICAgIH0KICAgIHZhbHVlID0gdG9OdW1iZXIkMSh2YWx1ZSk7CiAgICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHsKICAgICAgdmFyIHNpZ24gPSB2YWx1ZSA8IDAgPyAtMSA6IDE7CiAgICAgIHJldHVybiBzaWduICogTUFYX0lOVEVHRVI7CiAgICB9CiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gdmFsdWUgOiAwOwogIH07CiAgdmFyIHRvSW50ZWdlciA9IGZ1bmN0aW9uIHRvSW50ZWdlcih2YWx1ZSkgewogICAgdmFyIHJlc3VsdCA9IHRvRmluaXRlKHZhbHVlKTsKICAgIHZhciByZW1haW5kZXIgPSByZXN1bHQgJSAxOwogICAgcmV0dXJuIHJlc3VsdCA9PT0gcmVzdWx0ID8gcmVtYWluZGVyID8gcmVzdWx0IC0gcmVtYWluZGVyIDogcmVzdWx0IDogMDsKICB9OwoKICB2YXIgaW50ZXJjZXB0ID0gZnVuY3Rpb24gaW50ZXJjZXB0KG51bWJlcikgewogICAgdmFyIF9kZWNpbWFsID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiA4OwogICAgdmFyIG51bSA9IE51bWJlcihudW1iZXIpOwogICAgaWYgKGlzTmFOJDEobnVtKSB8fCAhaXNGaW5pdGUkMShudW0pKSB7CiAgICAgIG51bSA9IDA7CiAgICB9CiAgICB2YXIgZGVjaW1hbCA9IE51bWJlcihfZGVjaW1hbCk7CiAgICBpZiAoaXNOYU4kMShkZWNpbWFsKSkgewogICAgICBkZWNpbWFsID0gODsKICAgIH0KICAgIHZhciBudW1TdHIgPSAnJzsKICAgIGlmIChpc0ludGVnZXIobnVtKSkgewogICAgICBpZiAoZGVjaW1hbCA+IDApIHsKICAgICAgICBudW1TdHIgPSAiIi5jb25jYXQobnVtLCAiLiIpOwogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVjaW1hbDsgaSArPSAxKSB7CiAgICAgICAgICBudW1TdHIgPSAiIi5jb25jYXQobnVtU3RyLCAiMCIpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBudW1TdHIgPSAiIi5jb25jYXQobnVtKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgbnVtU3RyID0gU3RyaW5nKG51bSk7CiAgICAgIGlmIChudW1TdHIuaW5kZXhPZignZS0nKSA+PSAwIHx8IG51bVN0ci5pbmRleE9mKCdFLScpID49IDApIHsKICAgICAgICBudW1TdHIgPSBudW0udG9GaXhlZChkZWNpbWFsICsgMSk7CiAgICAgIH0KICAgICAgbnVtU3RyID0gbnVtU3RyLnNwbGl0KCcuJyk7CiAgICAgIHZhciBhcnJJbml0ID0gbnVtU3RyWzBdOwogICAgICBpZiAoZGVjaW1hbCA9PT0gMCkgewogICAgICAgIC8vIOS/ruWkjW51bT0xMS4xLGRlY2ltYWw9MOi/lOWbnjExLumXrumimAogICAgICAgIHJldHVybiAiIi5jb25jYXQoYXJySW5pdCk7CiAgICAgIH0KICAgICAgdmFyIGFyckRlY2ltYWwgPSBudW1TdHJbMV07CiAgICAgIGlmIChhcnJEZWNpbWFsLmxlbmd0aCA8IGRlY2ltYWwpIHsKICAgICAgICBudW1TdHIgPSAiIi5jb25jYXQoYXJySW5pdCwgIi4iKS5jb25jYXQoYXJyRGVjaW1hbCk7CiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGRlY2ltYWwgLSBhcnJEZWNpbWFsLmxlbmd0aDsgX2kgKz0gMSkgewogICAgICAgICAgbnVtU3RyID0gIiIuY29uY2F0KG51bVN0ciwgIjAiKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbnVtU3RyID0gIiIuY29uY2F0KGFyckluaXQsICIuIikuY29uY2F0KGFyckRlY2ltYWwuc3Vic3RyKDAsIGRlY2ltYWwpKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIG51bVN0cjsKICB9OwoKICB2YXIgVElDS19ESVJFQ1RJT04kMSA9IHsKICAgIFBMVVM6ICdQbHVzVGljaycsCiAgICBNSU5VUzogJ01pbnVzVGljaycsCiAgICBaRVJPX1BMVVM6ICdaZXJvUGx1c1RpY2snLAogICAgWkVST19NSU5VUzogJ1plcm9NaW51c1RpY2snCiAgfTsKICB2YXIgVElDS19ESVJFQ1RJT05fTUFQID0gewogICAgJysnOiBUSUNLX0RJUkVDVElPTiQxLlBMVVMsCiAgICAnLSc6IFRJQ0tfRElSRUNUSU9OJDEuTUlOVVMsCiAgICAnMCsnOiBUSUNLX0RJUkVDVElPTiQxLlpFUk9fUExVUywKICAgICcwLSc6IFRJQ0tfRElSRUNUSU9OJDEuWkVST19NSU5VUwogIH07CiAgdmFyIElOU1RSVU1FTlRfS0VZX01BUCA9IHsKICAgIHM6ICdzeW1ib2wnLAogICAgcDogJ2xhc3RQcmljZScsCiAgICBiMTogJ2JpZDFQcmljZScsCiAgICBhMTogJ2FzazFQcmljZScsCiAgICBwMjogJ3ByZXZQcmljZTI0aCcsCiAgICBwMTogJ3ByZXZQcmljZTFoJywKICAgIHByOiAncHJpY2UyNGhQY250RTYnLAogICAgaDogJ2hpZ2hQcmljZTI0aCcsCiAgICBsOiAnbG93UHJpY2UyNGgnLAogICAgdGQ6ICdsYXN0VGlja0RpcmVjdGlvbicsCiAgICBtcDogJ21hcmtQcmljZScsCiAgICB4cDogJ2luZGV4UHJpY2UnLAogICAgbzogJ29wZW5JbnRlcmVzdCcsCiAgICB0bzogJ3R1cm5vdmVyMjRoJywKICAgIHY6ICd2b2x1bWUyNGgnLAogICAgZnI6ICdmdW5kaW5nUmF0ZUU2JywKICAgIGZ0OiAnbmV4dEZ1bmRpbmdUaW1lJywKICAgIHBmOiAncHJlZGljdGVkRnVuZGluZ1JhdGVFNicsCiAgICBuaDogJ2Z1bmRpbmdSYXRlSW50ZXJ2YWwnLAogICAgdHM6ICd0aW1lc3RhbXBFNicsCiAgICBkczogJ2RlbGlzdGluZ1N0YXR1cycsCiAgICBydDogJ3RpbWVUb1NldHRsZScsCiAgICBzdDogJ3NldHRsZVRpbWVFOScsCiAgICBmYjogJ2ZhaXJCYXNpc0U4JywKICAgIGJyOiAnZmFpckJhc2lzUmF0ZUU4JywKICAgIHlyOiAnYmFzaXNJblllYXJFOCcsCiAgICBlcDogJ2V4cGVjdFByaWNlJywKICAgIGZyZ3M6ICdmdW5kaW5nUmF0ZUdyYXlTeW1ib2wnLAogICAgcm86ICdyZWR1Y2VPbmx5JywKICAgIHBvcDogJ3ByZU9wZW5QcmljZScsCiAgICBjcGxwOiAnY3VyUHJlTGlzdGluZ1BoYXNlJywKICAgIG1wMTogJ2xlZzFNYXJrUHJpY2UnLAogICAgbXAyOiAnbGVnMk1hcmtQcmljZScsCiAgICBpcHA6ICdpbXBsaWVkUHJpY2UnLAogICAgYjFxOiAnYmlkMVF0eScsCiAgICBhMXE6ICdhc2sxUXR5JywKICAgIGFwcjogJ2FwcicsCiAgICB4MTogJ2Fza0ltcGxpZWRQcmljZU9mZnNldCcsCiAgICB4MjogJ2JpZEltcGxpZWRQcmljZU9mZnNldCcsCiAgICBjZnJjOiAnY3VycmVudEZ1bmRpbmdSYXRlQ2xhbXAnLAogICAgcGZyOiAncHJlRnVuZGluZ1JhdGVFNicsCiAgICBwbmg6ICdwcmVGdW5kaW5nSW50ZXJ2YWxIb3VyJwogIH07CiAgdmFyIE5VTUJFUl9LRVkgPSB7CiAgICBwOiAnbGFzdFByaWNlJywKICAgIGIxOiAnYmlkMVByaWNlJywKICAgIGExOiAnYXNrMVByaWNlJywKICAgIHAyOiAncHJldlByaWNlMjRoJywKICAgIHAxOiAncHJldlByaWNlMWgnLAogICAgcHI6ICdwcmljZTI0aFBjbnRFNicsCiAgICBoOiAnaGlnaFByaWNlMjRoJywKICAgIGw6ICdsb3dQcmljZTI0aCcsCiAgICBtcDogJ21hcmtQcmljZScsCiAgICB4cDogJ2luZGV4UHJpY2UnLAogICAgbzogJ29wZW5JbnRlcmVzdCcsCiAgICB0bzogJ3R1cm5vdmVyMjRoJywKICAgIHY6ICd2b2x1bWUyNGgnLAogICAgZnI6ICdmdW5kaW5nUmF0ZUU2JywKICAgIHBmOiAncHJlZGljdGVkRnVuZGluZ1JhdGVFNicsCiAgICBuaDogJ2Z1bmRpbmdSYXRlSW50ZXJ2YWwnLAogICAgcnQ6ICd0aW1lVG9TZXR0bGUnLAogICAgc3Q6ICdzZXR0bGVUaW1lRTknLAogICAgZmI6ICdmYWlyQmFzaXNFOCcsCiAgICBicjogJ2ZhaXJCYXNpc1JhdGVFOCcsCiAgICB5cjogJ2Jhc2lzSW5ZZWFyRTgnLAogICAgZXA6ICdleHBlY3RQcmljZScsCiAgICBtcDE6ICdsZWcxTWFya1ByaWNlJywKICAgIG1wMjogJ2xlZzJNYXJrUHJpY2UnLAogICAgaXBwOiAnaW1wbGllZFByaWNlJywKICAgIGIxcTogJ2JpZDFRdHknLAogICAgYTFxOiAnYXNrMVF0eScsCiAgICBhcHI6ICdhcHInLAogICAgeDE6ICdhc2tJbXBsaWVkUHJpY2VPZmZzZXQnLAogICAgeDI6ICdiaWRJbXBsaWVkUHJpY2VPZmZzZXQnCiAgfTsKCiAgLy8gTk9USUNFOiDkv67mlLnmlbDmja7nu5PmnoTvvJpNQVBQSU5H5a+56LGh5a2Y5YKo77yM5Y+v5Lul5a2Y5YKo5aSa5Liq77yM6Ziy5q2i6K6i6ZiF5aSa5LiqaW5zdHJ1bWVudOaXtuWvvOiHtOaVsOaNruW8guW4uAogIC8vIGxldCBpbnN0cnVtZW50U3RvcmU6IElJbnN0cnVtZW50ID0geyBzeW1ib2w6ICcnIH07CiAgdmFyIGluc3RydW1lbnRTdG9yZSQxID0ge307CiAgdmFyIHRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIocGFyYW0pIHsKICAgIHZhciByZXN1bHQ7CiAgICBpZiAodHlwZW9mIHBhcmFtID09PSAnbnVtYmVyJykgewogICAgICByZXN1bHQgPSBwYXJhbTsKICAgIH0gZWxzZSBpZiAodHlwZW9mIHBhcmFtID09PSAnc3RyaW5nJykgewogICAgICByZXN1bHQgPSArcGFyYW07CiAgICB9IGVsc2UgewogICAgICByZXN1bHQgPSBOYU47CiAgICB9CiAgICByZXR1cm4gcmVzdWx0OwogIH07CiAgdmFyIGhhbmRsZUluc3RydW1lbnQkMiA9IGZ1bmN0aW9uIGhhbmRsZUluc3RydW1lbnQoaW5zdHJ1bWVudCkgewogICAgdmFyIHJlc3VsdCA9IHsKICAgICAgc3ltYm9sOiAnJwogICAgfTsKICAgIE9iamVjdC5lbnRyaWVzKGluc3RydW1lbnQpLmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHsKICAgICAgdmFyIF9yZWYyID0gX3NsaWNlZFRvQXJyYXkoX3JlZiwgMiksCiAgICAgICAga2V5ID0gX3JlZjJbMF0sCiAgICAgICAgdmFsdWUgPSBfcmVmMlsxXTsKICAgICAgaWYgKElOU1RSVU1FTlRfS0VZX01BUFtrZXldKSB7CiAgICAgICAgcmVzdWx0W0lOU1RSVU1FTlRfS0VZX01BUFtrZXldXSA9IE5VTUJFUl9LRVlba2V5XSA/IHRvTnVtYmVyKHZhbHVlKSA6IHZhbHVlOwogICAgICAgIGlmIChrZXkgPT09ICd0ZCcpIHsKICAgICAgICAgIHJlc3VsdC5sYXN0VGlja0RpcmVjdGlvbiA9IHZhbHVlID8gVElDS19ESVJFQ1RJT05fTUFQW3ZhbHVlXSA6IHVuZGVmaW5lZDsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZTsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gcmVzdWx0OwogIH07CiAgdmFyIGluc3RydW1lbnRTbmFwc2hvdEZuJDEgPSBmdW5jdGlvbiBpbnN0cnVtZW50U25hcHNob3RGbihzeW1ib2wsIGluc3RydW1lbnQpIHsKICAgIGluc3RydW1lbnRTdG9yZSQxW3N5bWJvbF0gPSBoYW5kbGVJbnN0cnVtZW50JDIoaW5zdHJ1bWVudCk7CiAgICByZXR1cm4gaW5zdHJ1bWVudFN0b3JlJDFbc3ltYm9sXTsKICB9OwogIHZhciBpbnN0cnVtZW50RGV0YWxGbiQxID0gZnVuY3Rpb24gaW5zdHJ1bWVudERldGFsRm4oc3ltYm9sLCBpbnN0cnVtZW50KSB7CiAgICBpbnN0cnVtZW50U3RvcmUkMVtzeW1ib2xdID0gX29iamVjdFNwcmVhZDIkMihfb2JqZWN0U3ByZWFkMiQyKHt9LCBpbnN0cnVtZW50U3RvcmUkMVtzeW1ib2xdKSwgaGFuZGxlSW5zdHJ1bWVudCQyKGluc3RydW1lbnQpKTsKICAgIHJldHVybiBpbnN0cnVtZW50U3RvcmUkMVtzeW1ib2xdOwogIH07CgogIC8vIE5PVElDRTog5L+u5pS55pWw5o2u57uT5p6E77yaTUFQUElOR+WvueixoeWtmOWCqO+8jOWPr+S7peWtmOWCqOWkmuS4qu+8jOmYsuatouiuoumYheWkmuS4qmluc3RydW1lbnTml7blr7zoh7TmlbDmja7lvILluLgKICAvLyBpbnN0cnVtZW50X2luZm9fdjMuYWxsIOWinumHj+WkhOeQhgogIHZhciBpbnN0cnVtZW50TGlzdCQyID0gW107CiAgLy8g5YWo6YeP5pWw5o2uIOWkhOeQhgogIHZhciBpbnN0cnVtZW50QWxsU25hcHNob3RGbiQyID0gZnVuY3Rpb24gaW5zdHJ1bWVudEFsbFNuYXBzaG90Rm4oaW5zdHJ1bWVudHMpIHsKICAgIHZhciByZXN1bHRMaXN0ID0gW107CiAgICBpbnN0cnVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgIHJlc3VsdExpc3QucHVzaChoYW5kbGVJbnN0cnVtZW50JDIoaXRlbSkpOwogICAgfSk7CiAgICAvLyDlhajph4/mm7TmlrAKICAgIGluc3RydW1lbnRMaXN0JDIgPSByZXN1bHRMaXN0OwogICAgcmV0dXJuIGluc3RydW1lbnRMaXN0JDI7CiAgfTsKICAvLyDlop7ph4/mlbDmja4g5aSE55CGCiAgdmFyIGluc3RydW1lbnRBbGxEZXRhbEZuJDIgPSBmdW5jdGlvbiBpbnN0cnVtZW50QWxsRGV0YWxGbihpbnN0cnVtZW50cykgewogICAgaW5zdHJ1bWVudHMuZm9yRWFjaChmdW5jdGlvbiAoaW5zKSB7CiAgICAgIHZhciBpbnNJdGVtID0gaGFuZGxlSW5zdHJ1bWVudCQyKGlucyk7CiAgICAgIHZhciB0YXJnZXRJbmRleCA9IGluc3RydW1lbnRMaXN0JDIuZmluZEluZGV4KGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgcmV0dXJuIGl0ZW0uc3ltYm9sID09PSBpbnNJdGVtLnN5bWJvbDsKICAgICAgfSk7CiAgICAgIGlmICh0YXJnZXRJbmRleCA+IC0xKSB7CiAgICAgICAgLy8g5a2Y5Zyo5ZCI5bm2CiAgICAgICAgdmFyIHRhcmdlSW5zID0gaW5zdHJ1bWVudExpc3QkMlt0YXJnZXRJbmRleF07CiAgICAgICAgaW5zdHJ1bWVudExpc3QkMlt0YXJnZXRJbmRleF0gPSBfb2JqZWN0U3ByZWFkMiQyKF9vYmplY3RTcHJlYWQyJDIoe30sIHRhcmdlSW5zKSwgaW5zSXRlbSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8g5LiN5a2Y5ZyoIOaWsOWingogICAgICAgIGluc3RydW1lbnRMaXN0JDIucHVzaChpbnNJdGVtKTsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gaW5zdHJ1bWVudExpc3QkMjsKICB9OwogIC8vIGV4cG9ydCBjb25zdCBnZXRJbnN0cnVtZW50QWxsU25hcFNob3QgPSAoKTogSUluc3RydW1lbnRbXSA9PiBpbnN0cnVtZW50TGlzdDsKCiAgdmFyIHRvTnVtYmVyWmVybyA9IGZ1bmN0aW9uIHRvTnVtYmVyWmVybyhudW1iZXIpIHsKICAgIHJldHVybiBOdW1iZXIobnVtYmVyKSB8fCAwOwogIH07CiAgLy8gSW5zdHJ1bWVudEluZm9BbGwg5pS55Li65aKe6YeP5aSE55CGCiAgdmFyIGhhbmRsZUFsbFN5bWJvbCQxID0gZnVuY3Rpb24gaGFuZGxlQWxsU3ltYm9sKG9yaWdpbmFsTWVzc2FnZSkgewogICAgdmFyIGRhdGEgPSBvcmlnaW5hbE1lc3NhZ2UuZGF0YSwKICAgICAgdHlwZSA9IG9yaWdpbmFsTWVzc2FnZS50eXBlOwogICAgLy8gcmVzZXTnoa7orqQKICAgIGlmICh0eXBlID09PSAnc25hcHNob3QnIHx8IHR5cGUgPT09ICdyZXNldCcpIHsKICAgICAgb3JpZ2luYWxNZXNzYWdlLmRhdGEgPSBpbnN0cnVtZW50QWxsU25hcHNob3RGbiQyKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgb3JpZ2luYWxNZXNzYWdlLmRhdGEgPSBpbnN0cnVtZW50QWxsRGV0YWxGbiQyKGRhdGEpOwogICAgfQogICAgcmV0dXJuIG9yaWdpbmFsTWVzc2FnZTsKICB9OwogIHZhciBoYW5kbGVTaW5nbGVTeW1ib2wkMSA9IGZ1bmN0aW9uIGhhbmRsZVNpbmdsZVN5bWJvbChzeW1ib2wsIG9yaWdpbmFsTWVzc2FnZSkgewogICAgdmFyIHR5cGUgPSBvcmlnaW5hbE1lc3NhZ2UudHlwZSwKICAgICAgZGF0YSA9IG9yaWdpbmFsTWVzc2FnZS5kYXRhLAogICAgICB0cyA9IG9yaWdpbmFsTWVzc2FnZS50cywKICAgICAgdGltZXN0YW1wRTYgPSBvcmlnaW5hbE1lc3NhZ2UudGltZXN0YW1wRTY7CiAgICB2YXIgcmVzdWx0ID0gX29iamVjdFNwcmVhZDIkMihfb2JqZWN0U3ByZWFkMiQyKHt9LCBkYXRhKSwge30sIHsKICAgICAgdHM6IHRzIHx8IHRpbWVzdGFtcEU2CiAgICB9KTsKICAgIGlmICh0eXBlID09PSAnc25hcHNob3QnIHx8IHR5cGUgPT09ICdyZXNldCcpIHsKICAgICAgcmVzdWx0ID0gaW5zdHJ1bWVudFNuYXBzaG90Rm4kMShzeW1ib2wsIHJlc3VsdCk7CiAgICB9IGVsc2UgewogICAgICByZXN1bHQgPSBpbnN0cnVtZW50RGV0YWxGbiQxKHN5bWJvbCwgcmVzdWx0KTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKICB2YXIgVElDS19ESVJFQ1RJT04gPSB7CiAgICBQTFVTOiAnUGx1c1RpY2snLAogICAgTUlOVVM6ICdNaW51c1RpY2snLAogICAgWkVST19QTFVTOiAnWmVyb1BsdXNUaWNrJywKICAgIFpFUk9fTUlOVVM6ICdaZXJvTWludXNUaWNrJwogIH07CiAgdmFyIGZvcm1hdENoYW5nZVByaWNlID0gZnVuY3Rpb24gZm9ybWF0Q2hhbmdlUHJpY2UobGFzdFByaWNlLCBvcGVuUHJpY2UpIHsKICAgIHZhciB0ZW1wQ2hhbmdlVHVybm92ZXIyNEggPSBsYXN0UHJpY2UgLSBvcGVuUHJpY2U7CiAgICB2YXIgdGVtcENoYW5nZVJhdGUyNEggPSB0ZW1wQ2hhbmdlVHVybm92ZXIyNEggLyBvcGVuUHJpY2U7CiAgICByZXR1cm4gewogICAgICBjaGFuZ2VSYXRlMjRIOiAodGVtcENoYW5nZVJhdGUyNEggKiAxMDApLnRvRml4ZWQoMiksCiAgICAgIGNoYW5nZVR1cm5vdmVyMjRIOiB0ZW1wQ2hhbmdlVHVybm92ZXIyNEgKICAgIH07CiAgfTsKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlbgogIHZhciBoYW5kbGVBbGxTeW1ib2xRdW90ZSA9IGZ1bmN0aW9uIGhhbmRsZUFsbFN5bWJvbFF1b3RlKGRhdGEsIG9wZW5QcmljZUxpc3QpIHsKICAgIHZhciBhbGxRdW90ZURhdGEgPSB7fTsKICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoY29uZmlnKSB7CiAgICAgIHZhciBsYXN0VGlja0RpcmVjdGlvbiA9IGNvbmZpZy5sYXN0VGlja0RpcmVjdGlvbiwKICAgICAgICBsYXN0UHJpY2UgPSBjb25maWcubGFzdFByaWNlLAogICAgICAgIG1hcmtQcmljZSA9IGNvbmZpZy5tYXJrUHJpY2UsCiAgICAgICAgaW5kZXhQcmljZSA9IGNvbmZpZy5pbmRleFByaWNlLAogICAgICAgIHZvbHVtZTI0aCA9IGNvbmZpZy52b2x1bWUyNGgsCiAgICAgICAgcHJpY2UyNGhQY250RTYgPSBjb25maWcucHJpY2UyNGhQY250RTYsCiAgICAgICAgdHVybm92ZXIyNGggPSBjb25maWcudHVybm92ZXIyNGgsCiAgICAgICAgc3ltYm9sID0gY29uZmlnLnN5bWJvbCwKICAgICAgICBhc2sxUHJpY2UgPSBjb25maWcuYXNrMVByaWNlLAogICAgICAgIGJpZDFQcmljZSA9IGNvbmZpZy5iaWQxUHJpY2U7CiAgICAgIHZhciBsYXN0UHJpY2VOdW0gPSB0b051bWJlclplcm8obGFzdFByaWNlKTsKICAgICAgdmFyIG1hcmtQcmljZU51bSA9IHRvTnVtYmVyWmVybyhtYXJrUHJpY2UpOwogICAgICB2YXIgaW5kZXhQcmljZU51bSA9IHRvTnVtYmVyWmVybyhpbmRleFByaWNlKTsKICAgICAgdmFyIGZvcm1hdHRlZExhc3RQcmljZSA9IGxhc3RQcmljZU51bTsKICAgICAgdmFyIGZvcm1hdHRlZFZvbHVtZTI0aCA9IHRvTnVtYmVyWmVybyh2b2x1bWUyNGgpOwogICAgICB2YXIgdHVybm92ZXIyNGhOdW1iZXIgPSB0b051bWJlclplcm8odHVybm92ZXIyNGgpIC8gMTsKICAgICAgdmFyIGlzTGFzdFByaWNlUGx1cyA9IFRJQ0tfRElSRUNUSU9OLlBMVVMgPT09IGxhc3RUaWNrRGlyZWN0aW9uIHx8IFRJQ0tfRElSRUNUSU9OLlpFUk9fUExVUyA9PT0gbGFzdFRpY2tEaXJlY3Rpb247CiAgICAgIHZhciBpc0xhc3RQcmljZU1pbnVzID0gVElDS19ESVJFQ1RJT04uTUlOVVMgPT09IGxhc3RUaWNrRGlyZWN0aW9uIHx8IFRJQ0tfRElSRUNUSU9OLlpFUk9fTUlOVVMgPT09IGxhc3RUaWNrRGlyZWN0aW9uOwogICAgICB2YXIgY2hhbmdlUmF0ZTI0SCA9IHRvTnVtYmVyWmVybyhpbnRlcmNlcHQoKHByaWNlMjRoUGNudEU2ICE9PSBudWxsICYmIHByaWNlMjRoUGNudEU2ICE9PSB2b2lkIDAgPyBwcmljZTI0aFBjbnRFNiA6IDApIC8gMWU0LCAyKSk7CiAgICAgIGlmIChvcGVuUHJpY2VMaXN0ICYmIE51bWJlcihvcGVuUHJpY2VMaXN0W3N5bWJvbF0pID4gMCkgewogICAgICAgIHZhciBjdXJPcGVuUHJpY2UgPSBvcGVuUHJpY2VMaXN0W3N5bWJvbF07CiAgICAgICAgaXNMYXN0UHJpY2VQbHVzID0gbGFzdFByaWNlTnVtID4gY3VyT3BlblByaWNlOwogICAgICAgIGlzTGFzdFByaWNlTWludXMgPSBsYXN0UHJpY2VOdW0gPCBjdXJPcGVuUHJpY2U7CiAgICAgICAgdmFyIGZvcm1hdHRlZFZhbHVlID0gZm9ybWF0Q2hhbmdlUHJpY2UobGFzdFByaWNlTnVtLCBjdXJPcGVuUHJpY2UpOwogICAgICAgIGNoYW5nZVJhdGUyNEggPSBOdW1iZXIoZm9ybWF0dGVkVmFsdWUuY2hhbmdlUmF0ZTI0SCk7CiAgICAgIH0KICAgICAgYWxsUXVvdGVEYXRhW3N5bWJvbF0gPSB7CiAgICAgICAgYXNrMVByaWNlOiBhc2sxUHJpY2UsCiAgICAgICAgYmlkMVByaWNlOiBiaWQxUHJpY2UsCiAgICAgICAgc3ltYm9sOiBzeW1ib2wsCiAgICAgICAgbGFzdFByaWNlTnVtYmVyOiBsYXN0UHJpY2VOdW0sCiAgICAgICAgbWFya1ByaWNlTnVtYmVyOiBtYXJrUHJpY2VOdW0sCiAgICAgICAgaW5kZXhQcmljZU51bWJlcjogaW5kZXhQcmljZU51bSwKICAgICAgICBsYXN0UHJpY2U6IGxhc3RQcmljZU51bSwKICAgICAgICBtYXJrUHJpY2U6IG1hcmtQcmljZU51bSwKICAgICAgICBpbmRleFByaWNlOiBpbmRleFByaWNlTnVtLAogICAgICAgIGZvcm1hdHRlZExhc3RQcmljZTogZm9ybWF0dGVkTGFzdFByaWNlLAogICAgICAgIHZvbHVtZTI0aDogZm9ybWF0dGVkVm9sdW1lMjRoLAogICAgICAgIGlzTGFzdFByaWNlUGx1czogaXNMYXN0UHJpY2VQbHVzLAogICAgICAgIGlzTGFzdFByaWNlTWludXM6IGlzTGFzdFByaWNlTWludXMsCiAgICAgICAgY2hhbmdlUmF0ZTI0SDogY2hhbmdlUmF0ZTI0SCwKICAgICAgICB0dXJub3ZlcjI0aDogdHVybm92ZXIyNGhOdW1iZXIsCiAgICAgICAgb3JpZ2luOiBfb2JqZWN0U3ByZWFkMiQyKHt9LCBjb25maWcpCiAgICAgIH07CiAgICB9KTsKICAgIHJldHVybiBhbGxRdW90ZURhdGE7CiAgfTsKCiAgLy8gTk9USUNFOiDkv67mlLnmlbDmja7nu5PmnoTvvJpNQVBQSU5H5a+56LGh5a2Y5YKo77yM5Y+v5Lul5a2Y5YKo5aSa5Liq77yM6Ziy5q2i6K6i6ZiF5aSa5LiqaW5zdHJ1bWVudOaXtuWvvOiHtOaVsOaNruW8guW4uAogIC8vIGxldCBpbnN0cnVtZW50U3RvcmU6IElJbnN0cnVtZW50ID0geyBzeW1ib2w6ICcnIH07CiAgdmFyIGluc3RydW1lbnRTdG9yZSA9IHt9OwogIHZhciBoYW5kbGVJbnN0cnVtZW50JDEgPSBmdW5jdGlvbiBoYW5kbGVJbnN0cnVtZW50KGluc3RydW1lbnQpIHsKICAgIHZhciByZXN1bHQgPSB7CiAgICAgIHN5bWJvbDogJycKICAgIH07CiAgICBPYmplY3QuZW50cmllcyhpbnN0cnVtZW50KS5mb3JFYWNoKGZ1bmN0aW9uIChfcmVmKSB7CiAgICAgIHZhciBfcmVmMiA9IF9zbGljZWRUb0FycmF5KF9yZWYsIDIpLAogICAgICAgIGtleSA9IF9yZWYyWzBdLAogICAgICAgIHZhbHVlID0gX3JlZjJbMV07CiAgICAgIGlmIChJTlNUUlVNRU5UX0tFWV9NQVBba2V5XSkgewogICAgICAgIHJlc3VsdFtJTlNUUlVNRU5UX0tFWV9NQVBba2V5XV0gPSB2YWx1ZTsKICAgICAgICBpZiAoa2V5ID09PSAndGQnKSB7CiAgICAgICAgICByZXN1bHQubGFzdFRpY2tEaXJlY3Rpb24gPSB2YWx1ZSA/IFRJQ0tfRElSRUNUSU9OX01BUFt2YWx1ZV0gOiB1bmRlZmluZWQ7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7CiAgICAgIH0KICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdDsKICB9OwogIHZhciBpbnN0cnVtZW50U25hcHNob3RGbiA9IGZ1bmN0aW9uIGluc3RydW1lbnRTbmFwc2hvdEZuKHN5bWJvbCwgaW5zdHJ1bWVudCkgewogICAgaW5zdHJ1bWVudFN0b3JlW3N5bWJvbF0gPSBoYW5kbGVJbnN0cnVtZW50JDEoaW5zdHJ1bWVudCk7CiAgICByZXR1cm4gaW5zdHJ1bWVudFN0b3JlW3N5bWJvbF07CiAgfTsKICB2YXIgaW5zdHJ1bWVudERldGFsRm4gPSBmdW5jdGlvbiBpbnN0cnVtZW50RGV0YWxGbihzeW1ib2wsIGluc3RydW1lbnQpIHsKICAgIGluc3RydW1lbnRTdG9yZVtzeW1ib2xdID0gX29iamVjdFNwcmVhZDIkMihfb2JqZWN0U3ByZWFkMiQyKHt9LCBpbnN0cnVtZW50U3RvcmVbc3ltYm9sXSksIGhhbmRsZUluc3RydW1lbnQkMShpbnN0cnVtZW50KSk7CiAgICByZXR1cm4gaW5zdHJ1bWVudFN0b3JlW3N5bWJvbF07CiAgfTsKCiAgLy8gTk9USUNFOiDkv67mlLnmlbDmja7nu5PmnoTvvJpNQVBQSU5H5a+56LGh5a2Y5YKo77yM5Y+v5Lul5a2Y5YKo5aSa5Liq77yM6Ziy5q2i6K6i6ZiF5aSa5LiqaW5zdHJ1bWVudOaXtuWvvOiHtOaVsOaNruW8guW4uAogIC8vIGluc3RydW1lbnRfaW5mb192My5hbGwg5aKe6YeP5aSE55CGCiAgdmFyIGluc3RydW1lbnRMaXN0JDEgPSBbXTsKICAvLyDlhajph4/mlbDmja4g5aSE55CGCiAgdmFyIGluc3RydW1lbnRBbGxTbmFwc2hvdEZuJDEgPSBmdW5jdGlvbiBpbnN0cnVtZW50QWxsU25hcHNob3RGbihpbnN0cnVtZW50cykgewogICAgdmFyIHJlc3VsdExpc3QgPSBbXTsKICAgIGluc3RydW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgcmVzdWx0TGlzdC5wdXNoKGhhbmRsZUluc3RydW1lbnQkMShpdGVtKSk7CiAgICB9KTsKICAgIC8vIOWFqOmHj+abtOaWsAogICAgaW5zdHJ1bWVudExpc3QkMSA9IHJlc3VsdExpc3Q7CiAgICByZXR1cm4gaW5zdHJ1bWVudExpc3QkMTsKICB9OwogIC8vIOWinumHj+aVsOaNriDlpITnkIYKICB2YXIgaW5zdHJ1bWVudEFsbERldGFsRm4kMSA9IGZ1bmN0aW9uIGluc3RydW1lbnRBbGxEZXRhbEZuKGluc3RydW1lbnRzKSB7CiAgICBpbnN0cnVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChpbnMpIHsKICAgICAgdmFyIGluc0l0ZW0gPSBoYW5kbGVJbnN0cnVtZW50JDEoaW5zKTsKICAgICAgdmFyIHRhcmdldEluZGV4ID0gaW5zdHJ1bWVudExpc3QkMS5maW5kSW5kZXgoZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICByZXR1cm4gaXRlbS5zeW1ib2wgPT09IGluc0l0ZW0uc3ltYm9sOwogICAgICB9KTsKICAgICAgaWYgKHRhcmdldEluZGV4ID4gLTEpIHsKICAgICAgICAvLyDlrZjlnKjlkIjlubYKICAgICAgICB2YXIgdGFyZ2VJbnMgPSBpbnN0cnVtZW50TGlzdCQxW3RhcmdldEluZGV4XTsKICAgICAgICBpbnN0cnVtZW50TGlzdCQxW3RhcmdldEluZGV4XSA9IF9vYmplY3RTcHJlYWQyJDIoX29iamVjdFNwcmVhZDIkMih7fSwgdGFyZ2VJbnMpLCBpbnNJdGVtKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyDkuI3lrZjlnKgg5paw5aKeCiAgICAgICAgaW5zdHJ1bWVudExpc3QkMS5wdXNoKGluc0l0ZW0pOwogICAgICB9CiAgICB9KTsKICAgIHJldHVybiBpbnN0cnVtZW50TGlzdCQxOwogIH07CiAgLy8gZXhwb3J0IGNvbnN0IGdldEluc3RydW1lbnRBbGxTbmFwU2hvdCA9ICgpOiBJSW5zdHJ1bWVudFtdID0+IGluc3RydW1lbnRMaXN0OwoKICAvLyBJbnN0cnVtZW50SW5mb0FsbCDmlLnkuLrlop7ph4/lpITnkIYKICB2YXIgaGFuZGxlQWxsU3ltYm9sID0gZnVuY3Rpb24gaGFuZGxlQWxsU3ltYm9sKG9yaWdpbmFsTWVzc2FnZSkgewogICAgdmFyIGRhdGEgPSBvcmlnaW5hbE1lc3NhZ2UuZGF0YSwKICAgICAgdHlwZSA9IG9yaWdpbmFsTWVzc2FnZS50eXBlOwogICAgLy8gcmVzZXTnoa7orqQKICAgIGlmICh0eXBlID09PSAnc25hcHNob3QnIHx8IHR5cGUgPT09ICdyZXNldCcpIHsKICAgICAgb3JpZ2luYWxNZXNzYWdlLmRhdGEgPSBpbnN0cnVtZW50QWxsU25hcHNob3RGbiQxKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgb3JpZ2luYWxNZXNzYWdlLmRhdGEgPSBpbnN0cnVtZW50QWxsRGV0YWxGbiQxKGRhdGEpOwogICAgfQogICAgcmV0dXJuIG9yaWdpbmFsTWVzc2FnZTsKICB9OwogIHZhciBoYW5kbGVTaW5nbGVTeW1ib2wgPSBmdW5jdGlvbiBoYW5kbGVTaW5nbGVTeW1ib2woc3ltYm9sLCBvcmlnaW5hbE1lc3NhZ2UpIHsKICAgIHZhciB0eXBlID0gb3JpZ2luYWxNZXNzYWdlLnR5cGUsCiAgICAgIGRhdGEgPSBvcmlnaW5hbE1lc3NhZ2UuZGF0YSwKICAgICAgdHMgPSBvcmlnaW5hbE1lc3NhZ2UudHMsCiAgICAgIHRpbWVzdGFtcEU2ID0gb3JpZ2luYWxNZXNzYWdlLnRpbWVzdGFtcEU2OwogICAgdmFyIHJlc3VsdCA9IF9vYmplY3RTcHJlYWQyJDIoX29iamVjdFNwcmVhZDIkMih7fSwgZGF0YSksIHt9LCB7CiAgICAgIHRzOiB0cyB8fCB0aW1lc3RhbXBFNgogICAgfSk7CiAgICBpZiAodHlwZSA9PT0gJ3NuYXBzaG90JyB8fCB0eXBlID09PSAncmVzZXQnKSB7CiAgICAgIHJlc3VsdCA9IGluc3RydW1lbnRTbmFwc2hvdEZuKHN5bWJvbCwgcmVzdWx0KTsKICAgIH0gZWxzZSB7CiAgICAgIHJlc3VsdCA9IGluc3RydW1lbnREZXRhbEZuKHN5bWJvbCwgcmVzdWx0KTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKCiAgLyoqCiAgICogQGRlc2NyaXB0aW9uIOi/lOWbnui/meS4quagt+W8j+eahOminOiJsuWAvAogICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIOagt+W8j+WQjeensCBbIHByaW1hcnkgfCBzdWNjZXNzIHwgd2FybmluZyB8IGRhbmdlciB8IGluZm8gXQogICAqLwogIHZhciB0eXBlQ29sb3IgPSBmdW5jdGlvbiB0eXBlQ29sb3IoKSB7CiAgICB2YXIgdHlwZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJ2RlZmF1bHQnOwogICAgdmFyIGNvbG9yID0gJyc7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgY2FzZSAncHJpbWFyeSc6CiAgICAgICAgY29sb3IgPSAnIzE5YmU2Yic7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ3N1Y2Nlc3MnOgogICAgICAgIGNvbG9yID0gJyMxOWJlNmInOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdpbmZvJzoKICAgICAgICBjb2xvciA9ICcjOTA5Mzk5JzsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnd2FybmluZyc6CiAgICAgICAgY29sb3IgPSAnI2ZmOTkwMCc7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ2Rhbmdlcic6CiAgICAgICAgY29sb3IgPSAnI2YwM2YxNCc7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ2RlZmF1bHQnOgogICAgICAgIGNvbG9yID0gJyMzNTQ5NUUnOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGNvbG9yID0gdHlwZTsKICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBjb2xvcjsKICB9OwogIC8qKgogICAqIOaJk+WNsOaWueazlQogICAqIEBwYXJhbSB0aXRsZSDovpPlh7rmlofmnKwKICAgKiBAcGFyYW0gdHlwZSDovpPlh7rmoLflvI/vvIzlj6/ku6XmmK825Liq54q25oCB5YC877yM5Lmf5Y+v5Lul5piv6Ieq5a6a5LmJ6aKc6ImyCiAgICogQHBhcmFtIGJhY2sg5piv5ZCm5bCG6Imy5YC85bqU55So5LqO6IOM5pmv6ImyCiAgICovCiAgdmFyIF9sb2dnZXIgPSBmdW5jdGlvbiBsb2dnZXIodGl0bGUpIHsKICAgIHZhciBkYXRhID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTsKICAgIHZhciB0eXBlID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAnc3VjY2Vzcyc7CiAgICB2YXIgYmFjayA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogdHJ1ZTsKICAgIGlmIChfdHlwZW9mJDEodGl0bGUpID09PSAnb2JqZWN0JykgewogICAgICAvLyDlpoLmnpzmmK/lr7nosaHliJnosIPnlKjmiZPljbDlr7nosaHmlrnlvI8KICAgICAgY29uc29sZS5kaXIodGl0bGUpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoYmFjaykgewogICAgICAvLyDlpoLmnpzmmK/miZPljbDluKbog4zmma/lm77nmoQKICAgICAgY29uc29sZS5ncm91cENvbGxhcHNlZCgiJWMgIi5jb25jYXQodGl0bGUsICIgIiksICJiYWNrZ3JvdW5kOiIuY29uY2F0KHR5cGVDb2xvcih0eXBlKSwgIjsgcGFkZGluZzogMnB4OyBib3JkZXItcmFkaXVzOiA0cHg7Y29sb3I6ICNmZmY7IikpOwogICAgICBfbG9nZ2VyKGRhdGEpOwogICAgICBjb25zb2xlLmdyb3VwRW5kKCk7CiAgICB9IGVsc2UgewogICAgICBjb25zb2xlLmxvZygiJWMgIi5jb25jYXQodGl0bGUsICIgIiksICJjb2xvcjogIi5jb25jYXQodHlwZUNvbG9yKHR5cGUpLCAiOyIpKTsKICAgIH0KICB9OwoKICAvKioKICAgKiBJbml0IHN0YXRlCiAgICovCiAgdmFyIHN0YXRlJDEgPSB7CiAgICBsb2FkZWQ6IGZhbHNlLAogICAgU2VsbDogW10sCiAgICBhc2sxSWQ6IDAsCiAgICBCdXk6IFtdLAogICAgYmlkMUlkOiAwLAogICAgYXNrMVByaWNlOiAwLAogICAgYmlkMVByaWNlOiAwLAogICAgZGVwdGhHcm91cGVkQnV5TGlzdDogW10sCiAgICBkZXB0aEdyb3VwZWRTZWxsTGlzdDogW10sCiAgICBzeW1ib2w6ICcnCiAgfTsKICB2YXIgZml4QnV5TGlzdCQyID0gZnVuY3Rpb24gZml4QnV5TGlzdChidXlMaXN0KSB7CiAgICB2YXIgYmlkSWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7CiAgICB3aGlsZSAoYnV5TGlzdCAmJiBiaWRJZCAhPT0gMCAmJiBidXlMaXN0Lmxlbmd0aCA+IDAgJiYgYnV5TGlzdFswXS5JZCA+IGJpZElkKSBidXlMaXN0LnNoaWZ0KCk7CiAgICByZXR1cm4gYnV5TGlzdDsKICB9OwogIHZhciBmaXhTZWxsTGlzdCQyID0gZnVuY3Rpb24gZml4U2VsbExpc3Qoc2VsbExpc3QpIHsKICAgIHZhciBhc2tJZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogMDsKICAgIHdoaWxlIChzZWxsTGlzdCAmJiBhc2tJZCAhPT0gMCAmJiBzZWxsTGlzdC5sZW5ndGggPiAwICYmIHNlbGxMaXN0W3NlbGxMaXN0Lmxlbmd0aCAtIDFdLklkIDwgYXNrSWQpIHsKICAgICAgc2VsbExpc3QucG9wKCk7CiAgICB9CiAgICByZXR1cm4gc2VsbExpc3Q7CiAgfTsKICB2YXIgc29ydE9iJDIgPSBmdW5jdGlvbiBzb3J0T2IoYSwgYikgewogICAgcmV0dXJuIGIuSWQgLSBhLklkOwogIH07CiAgdmFyIGNhbGNUb3RhbCQyID0gZnVuY3Rpb24gY2FsY1RvdGFsKHByZXYsIGN1cikgewogICAgcmV0dXJuIFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkocHJldiksIFtfb2JqZWN0U3ByZWFkMiQyKF9vYmplY3RTcHJlYWQyJDIoe30sIGN1ciksIHt9LCB7CiAgICAgIHRvdGFsOiAoY3VyLnNpemUgKiAxZTMgKyAocHJldi5sZW5ndGggPyBwcmV2W3ByZXYubGVuZ3RoIC0gMV0udG90YWwgfHwgMCA6IDApICogMWUzKSAvIDFlMwogICAgfSldKTsKICB9OwogIHZhciBoYW5kbGVPQiQyID0gZnVuY3Rpb24gaGFuZGxlT0IoKSB7CiAgICB2YXIgb3JkZXJib29rID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7CiAgICAgIGI6IFtdLAogICAgICBhOiBbXQogICAgfTsKICAgIHZhciBwcmljZVNjYWxlID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7CiAgICB2YXIgc3ltYm9sID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWQ7CiAgICB2YXIgX29yZGVyYm9vayRiID0gb3JkZXJib29rLmIsCiAgICAgIGIgPSBfb3JkZXJib29rJGIgPT09IHZvaWQgMCA/IFtdIDogX29yZGVyYm9vayRiLAogICAgICBfb3JkZXJib29rJGEgPSBvcmRlcmJvb2suYSwKICAgICAgYSA9IF9vcmRlcmJvb2skYSA9PT0gdm9pZCAwID8gW10gOiBfb3JkZXJib29rJGE7CiAgICB2YXIgYnV5TGlzdCA9IGIubWFwKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgIHJldHVybiBoYW5kbGVPQkl0ZW0kMihpdGVtLCBwcmljZVNjYWxlLCBPcmRlckFjdGlvbi5CVVksIHN5bWJvbCk7CiAgICB9KTsKICAgIHZhciBzZWxsTGlzdCA9IGEubWFwKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgIHJldHVybiBoYW5kbGVPQkl0ZW0kMihpdGVtLCBwcmljZVNjYWxlLCBPcmRlckFjdGlvbi5TRUxMLCBzeW1ib2wpOwogICAgfSk7CiAgICByZXR1cm4gW2J1eUxpc3QsIHNlbGxMaXN0XTsKICB9OwogIHZhciBoYW5kbGVPQkl0ZW0kMiA9IGZ1bmN0aW9uIGhhbmRsZU9CSXRlbShvYkl0ZW0sIHByaWNlU2NhbGUsIHNpZGUsIHN5bWJvbCkgewogICAgdmFyIF9vYkl0ZW0gPSBfc2xpY2VkVG9BcnJheShvYkl0ZW0sIDIpLAogICAgICBwcmljZSA9IF9vYkl0ZW1bMF0sCiAgICAgIHNpemUgPSBfb2JJdGVtWzFdOwogICAgdmFyIHByaWNlRCA9IG5ldyBEZWNpbWFsKHByaWNlKTsKICAgIHZhciBJZCA9IHByaWNlRC5tdWwocHJpY2VTY2FsZSkudG9OdW1iZXIoKTsKICAgIHJldHVybiB7CiAgICAgIElkOiBJZCwKICAgICAgcHJpY2U6IHByaWNlRC50b051bWJlcigpLAogICAgICBzaWRlOiBzaWRlLAogICAgICBzaXplOiBuZXcgRGVjaW1hbChzaXplKS50b051bWJlcigpLAogICAgICBzeW1ib2w6IHN5bWJvbCwKICAgICAgdG90YWw6IDAKICAgIH07CiAgfTsKICB2YXIgc2V0QXNrQmlkUHJpY2UkMiA9IGZ1bmN0aW9uIHNldEFza0JpZFByaWNlKCkgewogICAgdmFyIG9yZGVyYm9vayA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogewogICAgICBiOiBbXSwKICAgICAgYTogW10KICAgIH07CiAgICB2YXIgcHJpY2VTY2FsZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkOwogICAgdmFyIF9vcmRlcmJvb2skYTIgPSBvcmRlcmJvb2suYTEsCiAgICAgIGExID0gX29yZGVyYm9vayRhMiA9PT0gdm9pZCAwID8gJzAnIDogX29yZGVyYm9vayRhMiwKICAgICAgX29yZGVyYm9vayRiMiA9IG9yZGVyYm9vay5iMSwKICAgICAgYjEgPSBfb3JkZXJib29rJGIyID09PSB2b2lkIDAgPyAnMCcgOiBfb3JkZXJib29rJGIyOwogICAgc3RhdGUkMS5hc2sxUHJpY2UgPSBOdW1iZXIoYTEpOwogICAgdmFyIGFzazFJZCA9IG5ldyBEZWNpbWFsKGExKS5tdWwocHJpY2VTY2FsZSkudG9OdW1iZXIoKTsKICAgIHN0YXRlJDEuYXNrMUlkID0gYXNrMUlkOwogICAgc3RhdGUkMS5iaWQxUHJpY2UgPSBOdW1iZXIoYjEpOwogICAgdmFyIGJpZDFJZCA9IG5ldyBEZWNpbWFsKGIxKS5tdWwocHJpY2VTY2FsZSkudG9OdW1iZXIoKTsKICAgIHN0YXRlJDEuYmlkMUlkID0gYmlkMUlkOwogIH07CiAgdmFyIGdldFRvdGFsQ2FsY3VsYXRlZEFuZFNvcnRlZExpc3QkMiA9IGZ1bmN0aW9uIGdldFRvdGFsQ2FsY3VsYXRlZEFuZFNvcnRlZExpc3QoYnV5TGlzdCwgc2VsbExpc3QpIHsKICAgIHZhciBiaWQxSWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IDA7CiAgICB2YXIgYXNrMUlkID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiAwOwogICAgdmFyIG5ld0J1eUxpc3QgPSBmaXhCdXlMaXN0JDIoYnV5TGlzdC5zb3J0KHNvcnRPYiQyKSwgYmlkMUlkKTsKICAgIHZhciBuZXdTZWxsTGlzdCA9IGZpeFNlbGxMaXN0JDIoc2VsbExpc3Quc29ydChzb3J0T2IkMiksIGFzazFJZCk7CiAgICBuZXdCdXlMaXN0ID0gbmV3QnV5TGlzdC5yZWR1Y2UoY2FsY1RvdGFsJDIsIFtdKTsKICAgIG5ld1NlbGxMaXN0ID0gbmV3U2VsbExpc3QucmVkdWNlUmlnaHQoY2FsY1RvdGFsJDIsIFtdKS5yZXZlcnNlKCk7CiAgICByZXR1cm4gW25ld0J1eUxpc3QsIG5ld1NlbGxMaXN0XTsKICB9OwogIHZhciBvcmRlckJvb2tTbmFwc2hvdEZuJDIgPSBmdW5jdGlvbiBvcmRlckJvb2tTbmFwc2hvdEZuKCkgewogICAgdmFyIG9yZGVyYm9vayA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogewogICAgICBiOiBbXSwKICAgICAgYTogW10sCiAgICAgIGExOiAnMCcsCiAgICAgIGIxOiAnMCcKICAgIH07CiAgICB2YXIgc3ltYm9sID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7CiAgICB2YXIgX2hhbmRsZU9CID0gaGFuZGxlT0IkMihvcmRlcmJvb2ssIDEsIHN5bWJvbCksCiAgICAgIF9oYW5kbGVPQjIgPSBfc2xpY2VkVG9BcnJheShfaGFuZGxlT0IsIDIpLAogICAgICBidXlMaXN0ID0gX2hhbmRsZU9CMlswXSwKICAgICAgc2VsbExpc3QgPSBfaGFuZGxlT0IyWzFdOwogICAgdmFyIF9nZXRUb3RhbENhbGN1bGF0ZWRBbiA9IGdldFRvdGFsQ2FsY3VsYXRlZEFuZFNvcnRlZExpc3QkMihidXlMaXN0LCBzZWxsTGlzdCk7CiAgICB2YXIgX2dldFRvdGFsQ2FsY3VsYXRlZEFuMiA9IF9zbGljZWRUb0FycmF5KF9nZXRUb3RhbENhbGN1bGF0ZWRBbiwgMik7CiAgICBidXlMaXN0ID0gX2dldFRvdGFsQ2FsY3VsYXRlZEFuMlswXTsKICAgIHNlbGxMaXN0ID0gX2dldFRvdGFsQ2FsY3VsYXRlZEFuMlsxXTsKICAgIHZhciBhc2sxUHJpY2UgPSBOdW1iZXIob3JkZXJib29rLmExKTsKICAgIHZhciBiaWQxUHJpY2UgPSBOdW1iZXIob3JkZXJib29rLmIxKTsKICAgIHN0YXRlJDEgPSB7CiAgICAgIGxvYWRlZDogdHJ1ZSwKICAgICAgU2VsbDogc2VsbExpc3QsCiAgICAgIGFzazFJZDogYXNrMVByaWNlLAogICAgICBhc2sxUHJpY2U6IGFzazFQcmljZSwKICAgICAgQnV5OiBidXlMaXN0LAogICAgICBiaWQxSWQ6IGJpZDFQcmljZSwKICAgICAgYmlkMVByaWNlOiBiaWQxUHJpY2UsCiAgICAgIGRlcHRoR3JvdXBlZEJ1eUxpc3Q6IFtdLAogICAgICBkZXB0aEdyb3VwZWRTZWxsTGlzdDogW10sCiAgICAgIHN5bWJvbDogc3ltYm9sCiAgICB9OwogICAgcmV0dXJuIHN0YXRlJDE7CiAgfTsKICB2YXIgb3JkZXJCb29rRGVsdGFGbiQyID0gZnVuY3Rpb24gb3JkZXJCb29rRGVsdGFGbigpIHsKICAgIHZhciBvcmRlcmJvb2sgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHsKICAgICAgYjogW10sCiAgICAgIGE6IFtdLAogICAgICBhMTogJzAnLAogICAgICBiMTogJzAnCiAgICB9OwogICAgdmFyIHN5bWJvbCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkOwogICAgc2V0QXNrQmlkUHJpY2UkMihvcmRlcmJvb2ssIDEpOwogICAgdmFyIF9oYW5kbGVPQjMgPSBoYW5kbGVPQiQyKG9yZGVyYm9vaywgMSwgc3ltYm9sKSwKICAgICAgX2hhbmRsZU9CNCA9IF9zbGljZWRUb0FycmF5KF9oYW5kbGVPQjMsIDIpLAogICAgICBidXlMaXN0ID0gX2hhbmRsZU9CNFswXSwKICAgICAgc2VsbExpc3QgPSBfaGFuZGxlT0I0WzFdOwogICAgdmFyIF9zdGF0ZSA9IHN0YXRlJDEsCiAgICAgIEJ1eSA9IF9zdGF0ZS5CdXksCiAgICAgIFNlbGwgPSBfc3RhdGUuU2VsbDsKICAgIGJ1eUxpc3QuZm9yRWFjaChmdW5jdGlvbiAobmV3SXRlbSkgewogICAgICB2YXIgdGFyZ2V0SW5kZXggPSBCdXkuZmluZEluZGV4KGZ1bmN0aW9uIChzdGF0ZUl0ZW0pIHsKICAgICAgICByZXR1cm4gbmV3SXRlbS5JZCA9PT0gc3RhdGVJdGVtLklkOwogICAgICB9KTsKICAgICAgaWYgKHRhcmdldEluZGV4ID09PSAtMSkgewogICAgICAgIC8vIOayoeWMuemFjeWIsAogICAgICAgIGlmIChuZXdJdGVtLnNpemUgIT09IDApIHsKICAgICAgICAgIC8vIHNpemXkuI3kuLowID0+IOaWsOWingogICAgICAgICAgQnV5LnB1c2gobmV3SXRlbSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIOWMuemFjeWIsAogICAgICAgIGlmIChuZXdJdGVtLnNpemUgPT09IDApIHsKICAgICAgICAgIC8vIHNpemXkuLowID0+IOWIoOmZpAogICAgICAgICAgQnV5LnNwbGljZSh0YXJnZXRJbmRleCwgMSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIHNpemXkuI3kuLowID0+IOabv+aNogogICAgICAgICAgQnV5LnNwbGljZSh0YXJnZXRJbmRleCwgMSwgbmV3SXRlbSk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICAgIHNlbGxMaXN0LmZvckVhY2goZnVuY3Rpb24gKG5ld0l0ZW0pIHsKICAgICAgdmFyIHRhcmdldEluZGV4ID0gU2VsbC5maW5kSW5kZXgoZnVuY3Rpb24gKHN0YXRlSXRlbSkgewogICAgICAgIHJldHVybiBuZXdJdGVtLklkID09PSBzdGF0ZUl0ZW0uSWQ7CiAgICAgIH0pOwogICAgICBpZiAodGFyZ2V0SW5kZXggPT09IC0xKSB7CiAgICAgICAgLy8g5rKh5Yy56YWN5YiwCiAgICAgICAgaWYgKG5ld0l0ZW0uc2l6ZSAhPT0gMCkgewogICAgICAgICAgLy8gc2l6ZeS4jeS4ujAgPT4g5paw5aKeCiAgICAgICAgICBTZWxsLnB1c2gobmV3SXRlbSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIOWMuemFjeWIsAogICAgICAgIGlmIChuZXdJdGVtLnNpemUgPT09IDApIHsKICAgICAgICAgIC8vIHNpemXkuLowID0+IOWIoOmZpAogICAgICAgICAgU2VsbC5zcGxpY2UodGFyZ2V0SW5kZXgsIDEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBzaXpl5LiN5Li6MCA9PiDmm7/mjaIKICAgICAgICAgIFNlbGwuc3BsaWNlKHRhcmdldEluZGV4LCAxLCBuZXdJdGVtKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0pOwogICAgdmFyIF9nZXRUb3RhbENhbGN1bGF0ZWRBbjMgPSBnZXRUb3RhbENhbGN1bGF0ZWRBbmRTb3J0ZWRMaXN0JDIoc3RhdGUkMS5CdXksIHN0YXRlJDEuU2VsbCwgc3RhdGUkMS5iaWQxSWQsIHN0YXRlJDEuYXNrMUlkKTsKICAgIHZhciBfZ2V0VG90YWxDYWxjdWxhdGVkQW40ID0gX3NsaWNlZFRvQXJyYXkoX2dldFRvdGFsQ2FsY3VsYXRlZEFuMywgMik7CiAgICBzdGF0ZSQxLkJ1eSA9IF9nZXRUb3RhbENhbGN1bGF0ZWRBbjRbMF07CiAgICBzdGF0ZSQxLlNlbGwgPSBfZ2V0VG90YWxDYWxjdWxhdGVkQW40WzFdOwogICAgdmFyIGFzazFQcmljZSA9IE51bWJlcihvcmRlcmJvb2suYTEpOwogICAgdmFyIGJpZDFQcmljZSA9IE51bWJlcihvcmRlcmJvb2suYjEpOwogICAgaWYgKGFzazFQcmljZSkgewogICAgICBzdGF0ZSQxLmFzazFQcmljZSA9IGFzazFQcmljZTsKICAgIH0KICAgIGlmIChiaWQxUHJpY2UpIHsKICAgICAgc3RhdGUkMS5iaWQxUHJpY2UgPSBiaWQxUHJpY2U7CiAgICB9CiAgICBzdGF0ZSQxLnN5bWJvbCA9IHN5bWJvbDsKICAgIHJldHVybiBzdGF0ZSQxOwogIH07CiAgdmFyIG9yZGVyQm9va0hhbmRsZXIkMSA9IGZ1bmN0aW9uIG9yZGVyQm9va0hhbmRsZXIobmFtZVNwYWNlLCByZXN1bHQpIHsKICAgIHZhciB0eXBlID0gcmVzdWx0LnR5cGUsCiAgICAgIGRhdGEgPSByZXN1bHQuZGF0YTsKICAgIHJldHVybiB0eXBlID09PSAnc25hcHNob3QnID8gb3JkZXJCb29rU25hcHNob3RGbiQyKGRhdGEsIG5hbWVTcGFjZSkgOiBuYW1lU3BhY2UgPT09IHN0YXRlJDEuc3ltYm9sID8gb3JkZXJCb29rRGVsdGFGbiQyKGRhdGEsIG5hbWVTcGFjZSkgOiBzdGF0ZSQxOwogIH07CgogIC8qKgogICAqIEluaXQgc3RhdGUKICAgKi8KICB2YXIgc3RhdGUgPSB7CiAgICBsb2FkZWQ6IGZhbHNlLAogICAgU2VsbDogW10sCiAgICBhc2sxSWQ6IDAsCiAgICBCdXk6IFtdLAogICAgYmlkMUlkOiAwLAogICAgYXNrMVByaWNlOiAwLAogICAgYmlkMVByaWNlOiAwLAogICAgZGVwdGhHcm91cGVkQnV5TGlzdDogW10sCiAgICBkZXB0aEdyb3VwZWRTZWxsTGlzdDogW10sCiAgICBzeW1ib2w6ICcnCiAgfTsKICB2YXIgZml4QnV5TGlzdCQxID0gZnVuY3Rpb24gZml4QnV5TGlzdChidXlMaXN0KSB7CiAgICB2YXIgYmlkSWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7CiAgICB3aGlsZSAoYnV5TGlzdCAmJiBiaWRJZCAhPT0gMCAmJiBidXlMaXN0Lmxlbmd0aCA+IDAgJiYgYnV5TGlzdFswXS5JZCA+IGJpZElkKSBidXlMaXN0LnNoaWZ0KCk7CiAgICByZXR1cm4gYnV5TGlzdDsKICB9OwogIHZhciBmaXhTZWxsTGlzdCQxID0gZnVuY3Rpb24gZml4U2VsbExpc3Qoc2VsbExpc3QpIHsKICAgIHZhciBhc2tJZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogMDsKICAgIHdoaWxlIChzZWxsTGlzdCAmJiBhc2tJZCAhPT0gMCAmJiBzZWxsTGlzdC5sZW5ndGggPiAwICYmIHNlbGxMaXN0W3NlbGxMaXN0Lmxlbmd0aCAtIDFdLklkIDwgYXNrSWQpIHsKICAgICAgc2VsbExpc3QucG9wKCk7CiAgICB9CiAgICByZXR1cm4gc2VsbExpc3Q7CiAgfTsKICB2YXIgc29ydE9iJDEgPSBmdW5jdGlvbiBzb3J0T2IoYSwgYikgewogICAgcmV0dXJuIGIuSWQgLSBhLklkOwogIH07CiAgdmFyIGNhbGNUb3RhbCQxID0gZnVuY3Rpb24gY2FsY1RvdGFsKHByZXYsIGN1cikgewogICAgcmV0dXJuIFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkocHJldiksIFtfb2JqZWN0U3ByZWFkMiQyKF9vYmplY3RTcHJlYWQyJDIoe30sIGN1ciksIHt9LCB7CiAgICAgIHRvdGFsOiAoY3VyLnNpemUgKiAxZTMgKyAocHJldi5sZW5ndGggPyBwcmV2W3ByZXYubGVuZ3RoIC0gMV0udG90YWwgfHwgMCA6IDApICogMWUzKSAvIDFlMwogICAgfSldKTsKICB9OwogIHZhciBoYW5kbGVPQkl0ZW0kMSA9IGZ1bmN0aW9uIGhhbmRsZU9CSXRlbShvYkl0ZW0sIHByaWNlU2NhbGUsIHNpZGUsIHN5bWJvbCkgewogICAgdmFyIF9vYkl0ZW0gPSBfc2xpY2VkVG9BcnJheShvYkl0ZW0sIDIpLAogICAgICBwcmljZSA9IF9vYkl0ZW1bMF0sCiAgICAgIHNpemUgPSBfb2JJdGVtWzFdOwogICAgdmFyIHByaWNlRCA9IG5ldyBEZWNpbWFsKHByaWNlKTsKICAgIHZhciBJZCA9IHByaWNlRC5tdWwocHJpY2VTY2FsZSkudG9OdW1iZXIoKTsKICAgIHJldHVybiB7CiAgICAgIElkOiBJZCwKICAgICAgcHJpY2U6IHByaWNlRC50b051bWJlcigpLAogICAgICBzaWRlOiBzaWRlLAogICAgICBzaXplOiBuZXcgRGVjaW1hbChzaXplKS50b051bWJlcigpLAogICAgICBzeW1ib2w6IHN5bWJvbCwKICAgICAgdG90YWw6IDAKICAgIH07CiAgfTsKICB2YXIgaGFuZGxlT0IkMSA9IGZ1bmN0aW9uIGhhbmRsZU9CKCkgewogICAgdmFyIG9yZGVyYm9vayA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogewogICAgICBiOiBbXSwKICAgICAgYTogW10KICAgIH07CiAgICB2YXIgcHJpY2VTY2FsZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkOwogICAgdmFyIHN5bWJvbCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkOwogICAgdmFyIF9vcmRlcmJvb2skYiA9IG9yZGVyYm9vay5iLAogICAgICBiID0gX29yZGVyYm9vayRiID09PSB2b2lkIDAgPyBbXSA6IF9vcmRlcmJvb2skYiwKICAgICAgX29yZGVyYm9vayRhID0gb3JkZXJib29rLmEsCiAgICAgIGEgPSBfb3JkZXJib29rJGEgPT09IHZvaWQgMCA/IFtdIDogX29yZGVyYm9vayRhOwogICAgdmFyIGJ1eUxpc3QgPSBiLm1hcChmdW5jdGlvbiAoaXRlbSkgewogICAgICByZXR1cm4gaGFuZGxlT0JJdGVtJDEoaXRlbSwgcHJpY2VTY2FsZSwgT3JkZXJBY3Rpb24uQlVZLCBzeW1ib2wpOwogICAgfSk7CiAgICB2YXIgc2VsbExpc3QgPSBhLm1hcChmdW5jdGlvbiAoaXRlbSkgewogICAgICByZXR1cm4gaGFuZGxlT0JJdGVtJDEoaXRlbSwgcHJpY2VTY2FsZSwgT3JkZXJBY3Rpb24uU0VMTCwgc3ltYm9sKTsKICAgIH0pOwogICAgcmV0dXJuIFtidXlMaXN0LCBzZWxsTGlzdF07CiAgfTsKICB2YXIgc2V0QXNrQmlkUHJpY2UkMSA9IGZ1bmN0aW9uIHNldEFza0JpZFByaWNlKCkgewogICAgdmFyIG9yZGVyYm9vayA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogewogICAgICBiOiBbXSwKICAgICAgYTogW10KICAgIH07CiAgICB2YXIgcHJpY2VTY2FsZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkOwogICAgdmFyIF9vcmRlcmJvb2skYTIgPSBvcmRlcmJvb2suYTEsCiAgICAgIGExID0gX29yZGVyYm9vayRhMiA9PT0gdm9pZCAwID8gJzAnIDogX29yZGVyYm9vayRhMiwKICAgICAgX29yZGVyYm9vayRiMiA9IG9yZGVyYm9vay5iMSwKICAgICAgYjEgPSBfb3JkZXJib29rJGIyID09PSB2b2lkIDAgPyAnMCcgOiBfb3JkZXJib29rJGIyOwogICAgc3RhdGUuYXNrMVByaWNlID0gTnVtYmVyKGExKTsKICAgIHZhciBhc2sxSWQgPSBuZXcgRGVjaW1hbChhMSkubXVsKHByaWNlU2NhbGUpLnRvTnVtYmVyKCk7CiAgICBzdGF0ZS5hc2sxSWQgPSBhc2sxSWQ7CiAgICBzdGF0ZS5iaWQxUHJpY2UgPSBOdW1iZXIoYjEpOwogICAgdmFyIGJpZDFJZCA9IG5ldyBEZWNpbWFsKGIxKS5tdWwocHJpY2VTY2FsZSkudG9OdW1iZXIoKTsKICAgIHN0YXRlLmJpZDFJZCA9IGJpZDFJZDsKICB9OwogIHZhciBnZXRUb3RhbENhbGN1bGF0ZWRBbmRTb3J0ZWRMaXN0JDEgPSBmdW5jdGlvbiBnZXRUb3RhbENhbGN1bGF0ZWRBbmRTb3J0ZWRMaXN0KGJ1eUxpc3QsIHNlbGxMaXN0KSB7CiAgICB2YXIgYmlkMUlkID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAwOwogICAgdmFyIGFzazFJZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogMDsKICAgIHZhciBuZXdCdXlMaXN0ID0gZml4QnV5TGlzdCQxKGJ1eUxpc3Quc29ydChzb3J0T2IkMSksIGJpZDFJZCk7CiAgICB2YXIgbmV3U2VsbExpc3QgPSBmaXhTZWxsTGlzdCQxKHNlbGxMaXN0LnNvcnQoc29ydE9iJDEpLCBhc2sxSWQpOwogICAgbmV3QnV5TGlzdCA9IG5ld0J1eUxpc3QucmVkdWNlKGNhbGNUb3RhbCQxLCBbXSk7CiAgICBuZXdTZWxsTGlzdCA9IG5ld1NlbGxMaXN0LnJlZHVjZVJpZ2h0KGNhbGNUb3RhbCQxLCBbXSkucmV2ZXJzZSgpOwogICAgcmV0dXJuIFtuZXdCdXlMaXN0LCBuZXdTZWxsTGlzdF07CiAgfTsKICB2YXIgb3JkZXJCb29rU25hcHNob3RGbiQxID0gZnVuY3Rpb24gb3JkZXJCb29rU25hcHNob3RGbigpIHsKICAgIHZhciBvcmRlcmJvb2sgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHsKICAgICAgYjogW10sCiAgICAgIGE6IFtdLAogICAgICBhMTogJzAnLAogICAgICBiMTogJzAnCiAgICB9OwogICAgdmFyIHN5bWJvbCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkOwogICAgdmFyIF9oYW5kbGVPQiA9IGhhbmRsZU9CJDEob3JkZXJib29rLCAxLCBzeW1ib2wpLAogICAgICBfaGFuZGxlT0IyID0gX3NsaWNlZFRvQXJyYXkoX2hhbmRsZU9CLCAyKSwKICAgICAgYnV5TGlzdCA9IF9oYW5kbGVPQjJbMF0sCiAgICAgIHNlbGxMaXN0ID0gX2hhbmRsZU9CMlsxXTsKICAgIHZhciBfZ2V0VG90YWxDYWxjdWxhdGVkQW4gPSBnZXRUb3RhbENhbGN1bGF0ZWRBbmRTb3J0ZWRMaXN0JDEoYnV5TGlzdCwgc2VsbExpc3QpOwogICAgdmFyIF9nZXRUb3RhbENhbGN1bGF0ZWRBbjIgPSBfc2xpY2VkVG9BcnJheShfZ2V0VG90YWxDYWxjdWxhdGVkQW4sIDIpOwogICAgYnV5TGlzdCA9IF9nZXRUb3RhbENhbGN1bGF0ZWRBbjJbMF07CiAgICBzZWxsTGlzdCA9IF9nZXRUb3RhbENhbGN1bGF0ZWRBbjJbMV07CiAgICB2YXIgYXNrMVByaWNlID0gTnVtYmVyKG9yZGVyYm9vay5hMSk7CiAgICB2YXIgYmlkMVByaWNlID0gTnVtYmVyKG9yZGVyYm9vay5iMSk7CiAgICBzdGF0ZSA9IHsKICAgICAgbG9hZGVkOiB0cnVlLAogICAgICBTZWxsOiBzZWxsTGlzdCwKICAgICAgYXNrMUlkOiBhc2sxUHJpY2UsCiAgICAgIGFzazFQcmljZTogYXNrMVByaWNlLAogICAgICBCdXk6IGJ1eUxpc3QsCiAgICAgIGJpZDFJZDogYmlkMVByaWNlLAogICAgICBiaWQxUHJpY2U6IGJpZDFQcmljZSwKICAgICAgZGVwdGhHcm91cGVkQnV5TGlzdDogW10sCiAgICAgIGRlcHRoR3JvdXBlZFNlbGxMaXN0OiBbXSwKICAgICAgc3ltYm9sOiBzeW1ib2wKICAgIH07CiAgICByZXR1cm4gc3RhdGU7CiAgfTsKICB2YXIgb3JkZXJCb29rRGVsdGFGbiQxID0gZnVuY3Rpb24gb3JkZXJCb29rRGVsdGFGbigpIHsKICAgIHZhciBvcmRlcmJvb2sgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHsKICAgICAgYjogW10sCiAgICAgIGE6IFtdLAogICAgICBhMTogJzAnLAogICAgICBiMTogJzAnCiAgICB9OwogICAgdmFyIHN5bWJvbCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkOwogICAgc2V0QXNrQmlkUHJpY2UkMShvcmRlcmJvb2ssIDEpOwogICAgdmFyIF9oYW5kbGVPQjMgPSBoYW5kbGVPQiQxKG9yZGVyYm9vaywgMSwgc3ltYm9sKSwKICAgICAgX2hhbmRsZU9CNCA9IF9zbGljZWRUb0FycmF5KF9oYW5kbGVPQjMsIDIpLAogICAgICBidXlMaXN0ID0gX2hhbmRsZU9CNFswXSwKICAgICAgc2VsbExpc3QgPSBfaGFuZGxlT0I0WzFdOwogICAgdmFyIF9zdGF0ZSA9IHN0YXRlLAogICAgICBCdXkgPSBfc3RhdGUuQnV5LAogICAgICBTZWxsID0gX3N0YXRlLlNlbGw7CiAgICBidXlMaXN0LmZvckVhY2goZnVuY3Rpb24gKG5ld0l0ZW0pIHsKICAgICAgdmFyIHRhcmdldEluZGV4ID0gQnV5LmZpbmRJbmRleChmdW5jdGlvbiAoc3RhdGVJdGVtKSB7CiAgICAgICAgcmV0dXJuIG5ld0l0ZW0uSWQgPT09IHN0YXRlSXRlbS5JZDsKICAgICAgfSk7CiAgICAgIGlmICh0YXJnZXRJbmRleCA9PT0gLTEpIHsKICAgICAgICAvLyDmsqHljLnphY3liLAKICAgICAgICBpZiAobmV3SXRlbS5zaXplICE9PSAwKSB7CiAgICAgICAgICAvLyBzaXpl5LiN5Li6MCA9PiDmlrDlop4KICAgICAgICAgIEJ1eS5wdXNoKG5ld0l0ZW0pOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyDljLnphY3liLAKICAgICAgICBpZiAobmV3SXRlbS5zaXplID09PSAwKSB7CiAgICAgICAgICAvLyBzaXpl5Li6MCA9PiDliKDpmaQKICAgICAgICAgIEJ1eS5zcGxpY2UodGFyZ2V0SW5kZXgsIDEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBzaXpl5LiN5Li6MCA9PiDmm7/mjaIKICAgICAgICAgIEJ1eS5zcGxpY2UodGFyZ2V0SW5kZXgsIDEsIG5ld0l0ZW0pOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgICBzZWxsTGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChuZXdJdGVtKSB7CiAgICAgIHZhciB0YXJnZXRJbmRleCA9IFNlbGwuZmluZEluZGV4KGZ1bmN0aW9uIChzdGF0ZUl0ZW0pIHsKICAgICAgICByZXR1cm4gbmV3SXRlbS5JZCA9PT0gc3RhdGVJdGVtLklkOwogICAgICB9KTsKICAgICAgaWYgKHRhcmdldEluZGV4ID09PSAtMSkgewogICAgICAgIC8vIOayoeWMuemFjeWIsAogICAgICAgIGlmIChuZXdJdGVtLnNpemUgIT09IDApIHsKICAgICAgICAgIC8vIHNpemXkuI3kuLowID0+IOaWsOWingogICAgICAgICAgU2VsbC5wdXNoKG5ld0l0ZW0pOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyDljLnphY3liLAKICAgICAgICBpZiAobmV3SXRlbS5zaXplID09PSAwKSB7CiAgICAgICAgICAvLyBzaXpl5Li6MCA9PiDliKDpmaQKICAgICAgICAgIFNlbGwuc3BsaWNlKHRhcmdldEluZGV4LCAxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gc2l6ZeS4jeS4ujAgPT4g5pu/5o2iCiAgICAgICAgICBTZWxsLnNwbGljZSh0YXJnZXRJbmRleCwgMSwgbmV3SXRlbSk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICAgIHZhciBfZ2V0VG90YWxDYWxjdWxhdGVkQW4zID0gZ2V0VG90YWxDYWxjdWxhdGVkQW5kU29ydGVkTGlzdCQxKHN0YXRlLkJ1eSwgc3RhdGUuU2VsbCwgc3RhdGUuYmlkMUlkLCBzdGF0ZS5hc2sxSWQpOwogICAgdmFyIF9nZXRUb3RhbENhbGN1bGF0ZWRBbjQgPSBfc2xpY2VkVG9BcnJheShfZ2V0VG90YWxDYWxjdWxhdGVkQW4zLCAyKTsKICAgIHN0YXRlLkJ1eSA9IF9nZXRUb3RhbENhbGN1bGF0ZWRBbjRbMF07CiAgICBzdGF0ZS5TZWxsID0gX2dldFRvdGFsQ2FsY3VsYXRlZEFuNFsxXTsKICAgIHZhciBhc2sxUHJpY2UgPSBOdW1iZXIob3JkZXJib29rLmExKTsKICAgIHZhciBiaWQxUHJpY2UgPSBOdW1iZXIob3JkZXJib29rLmIxKTsKICAgIGlmIChhc2sxUHJpY2UpIHsKICAgICAgc3RhdGUuYXNrMVByaWNlID0gYXNrMVByaWNlOwogICAgfQogICAgaWYgKGJpZDFQcmljZSkgewogICAgICBzdGF0ZS5iaWQxUHJpY2UgPSBiaWQxUHJpY2U7CiAgICB9CiAgICBzdGF0ZS5zeW1ib2wgPSBzeW1ib2w7CiAgICByZXR1cm4gc3RhdGU7CiAgfTsKICB2YXIgb3JkZXJCb29rSGFuZGxlciA9IGZ1bmN0aW9uIG9yZGVyQm9va0hhbmRsZXIobmFtZVNwYWNlLCByZXN1bHQpIHsKICAgIHZhciB0eXBlID0gcmVzdWx0LnR5cGUsCiAgICAgIGRhdGEgPSByZXN1bHQuZGF0YTsKICAgIHJldHVybiB0eXBlID09PSAnc25hcHNob3QnID8gb3JkZXJCb29rU25hcHNob3RGbiQxKGRhdGEsIG5hbWVTcGFjZSkgOiBuYW1lU3BhY2UgPT09IHN0YXRlLnN5bWJvbCA/IG9yZGVyQm9va0RlbHRhRm4kMShkYXRhLCBuYW1lU3BhY2UpIDogc3RhdGU7CiAgfTsKCiAgdmFyIHJlY2VudFRyYWRlU3RvcmUkMSA9IHsKICAgIGxpc3Q6IFtdLAogICAgbG9hZGVkOiBmYWxzZQogIH07CiAgdmFyIGhhbmRsZVJUJDEgPSBmdW5jdGlvbiBoYW5kbGVSVChyZWNlbnRUcmFkZSwgc3ltYm9sKSB7CiAgICByZXR1cm4gcmVjZW50VHJhZGUubWFwKGZ1bmN0aW9uIChfcmVmKSB7CiAgICAgIHZhciBfcmVmMiA9IF9zbGljZWRUb0FycmF5KF9yZWYsIDcpLAogICAgICAgIHRpY2tEaXJlY3Rpb24gPSBfcmVmMlswXSwKICAgICAgICBleGVjUHJpY2UgPSBfcmVmMlsxXSwKICAgICAgICBleGVjUXR5ID0gX3JlZjJbMl0sCiAgICAgICAgZXhlY1RpbWUgPSBfcmVmMlszXSwKICAgICAgICBzaWRlID0gX3JlZjJbNF0sCiAgICAgICAgZXhlY0lkID0gX3JlZjJbNV0sCiAgICAgICAgdHJhZGVUeXBlID0gX3JlZjJbNl07CiAgICAgIHJldHVybiB7CiAgICAgICAgZXhlY0lkOiBleGVjSWQsCiAgICAgICAgZXhlY1ByaWNlOiBleGVjUHJpY2UsCiAgICAgICAgZXhlY1F0eTogZXhlY1F0eSwKICAgICAgICBleGVjVGltZTogZXhlY1RpbWUsCiAgICAgICAgc2lkZTogc2lkZSA9PT0gJ2InID8gT3JkZXJBY3Rpb24uQlVZIDogT3JkZXJBY3Rpb24uU0VMTCwKICAgICAgICBzeW1ib2w6IHN5bWJvbCwKICAgICAgICB0aWNrRGlyZWN0aW9uOiBUSUNLX0RJUkVDVElPTl9NQVBbdGlja0RpcmVjdGlvbl0sCiAgICAgICAgdHJhZGVUeXBlOiB0cmFkZVR5cGUKICAgICAgfTsKICAgIH0pOwogIH07CiAgdmFyIHJlY2VudFRyYWRlU25hcHNob3RGbiQxID0gZnVuY3Rpb24gcmVjZW50VHJhZGVTbmFwc2hvdEZuKHJlY2VudFRyYWRlLCBzeW1ib2wpIHsKICAgIHJlY2VudFRyYWRlU3RvcmUkMSA9IHsKICAgICAgbGlzdDogaGFuZGxlUlQkMShyZWNlbnRUcmFkZSwgc3ltYm9sKSwKICAgICAgbG9hZGVkOiB0cnVlCiAgICB9OwogICAgcmV0dXJuIHJlY2VudFRyYWRlU3RvcmUkMTsKICB9OwogIHZhciByZWNlbnRUcmFkZURlbHRhRm4kMSA9IGZ1bmN0aW9uIHJlY2VudFRyYWRlRGVsdGFGbihyZWNlbnRUcmFkZSwgc3ltYm9sKSB7CiAgICB2YXIgaGFuZGxlZFJlY2VudFRyYWRlID0gaGFuZGxlUlQkMShyZWNlbnRUcmFkZSwgc3ltYm9sKTsKICAgIHZhciBvbGRMZW4gPSByZWNlbnRUcmFkZVN0b3JlJDEubGlzdC5sZW5ndGg7CiAgICB2YXIgbmV3TGVuID0gaGFuZGxlZFJlY2VudFRyYWRlLmxlbmd0aDsKICAgIGlmIChvbGRMZW4gPT09IDAgfHwgb2xkTGVuID4gMCAmJiBEYXRlLnBhcnNlKGhhbmRsZWRSZWNlbnRUcmFkZVtuZXdMZW4gLSAxXS5leGVjVGltZSkgPj0gRGF0ZS5wYXJzZShyZWNlbnRUcmFkZVN0b3JlJDEubGlzdFswXS5leGVjVGltZSkpIHsKICAgICAgcmVjZW50VHJhZGVTdG9yZSQxLmxpc3QgPSBoYW5kbGVkUmVjZW50VHJhZGUucmV2ZXJzZSgpLmNvbmNhdChyZWNlbnRUcmFkZVN0b3JlJDEubGlzdCk7CiAgICB9CiAgICBpZiAocmVjZW50VHJhZGVTdG9yZSQxLmxpc3QubGVuZ3RoID4gMTAwKSB7CiAgICAgIHJlY2VudFRyYWRlU3RvcmUkMS5saXN0ID0gcmVjZW50VHJhZGVTdG9yZSQxLmxpc3Quc2xpY2UoMCwgMTAwKTsKICAgIH0KICAgIHJlY2VudFRyYWRlU3RvcmUkMS5sb2FkZWQgPSB0cnVlOwogICAgcmV0dXJuIHJlY2VudFRyYWRlU3RvcmUkMTsKICB9OwogIHZhciBnZXRSZWNlbnRUcmFkZVNuYXBzaG90JDEgPSBmdW5jdGlvbiBnZXRSZWNlbnRUcmFkZVNuYXBzaG90KCkgewogICAgcmV0dXJuIHJlY2VudFRyYWRlU3RvcmUkMTsKICB9OwogIHZhciByZWNlbnRUcmFkZUhhbmRsZXIkMSA9IGZ1bmN0aW9uIHJlY2VudFRyYWRlSGFuZGxlcihzeW1ib2wsIHJlc3VsdCkgewogICAgdmFyIF9yZWNlbnRUcmFkZVN0b3JlJGxpczsKICAgIHZhciB0eXBlID0gcmVzdWx0LnR5cGUsCiAgICAgIGRhdGEgPSByZXN1bHQuZGF0YTsKICAgIGlmICh0eXBlID09PSAnc25hcHNob3QnICYmIGRhdGEuZCkgewogICAgICByZXR1cm4gcmVjZW50VHJhZGVTbmFwc2hvdEZuJDEoZGF0YS5kLCBzeW1ib2wpOwogICAgfQogICAgaWYgKHR5cGUgPT09ICdkZWx0YScgJiYgZGF0YS5kICYmIGRhdGEuZC5sZW5ndGggJiYgKChfcmVjZW50VHJhZGVTdG9yZSRsaXMgPSByZWNlbnRUcmFkZVN0b3JlJDEubGlzdFswXSkgPT09IG51bGwgfHwgX3JlY2VudFRyYWRlU3RvcmUkbGlzID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfcmVjZW50VHJhZGVTdG9yZSRsaXMuc3ltYm9sKSA9PT0gZGF0YS5zKSB7CiAgICAgIC8vIHN5bWJvbCA9IGRhdGEucyDlkozorqLpmIXml7bmmK/kuIDoh7TnmoQKICAgICAgLy8gcmVjZW50VHJhZGVTdG9yZS5saXN0WzBdPy5zeW1ib2wgPT09IGRhdGEucyDnmoTpgLvovpHmmK/lnKjmjqjpgIHpmY3popHlkI7pooTpmLLlj6/og73kvJrlh7rnjrDnmoRzeW1ib2zliIfmjaLlr7zoh7TkuIrkuIDkuKrluIHlr7nnmoRkZWx0YeWMheaVsOaNrua3t+WFpQogICAgICByZXR1cm4gcmVjZW50VHJhZGVEZWx0YUZuJDEoZGF0YS5kLCBzeW1ib2wpOwogICAgfQogICAgcmV0dXJuIGdldFJlY2VudFRyYWRlU25hcHNob3QkMSgpOwogIH07CgogIHZhciByZWNlbnRUcmFkZVN0b3JlID0gewogICAgbGlzdDogW10sCiAgICBsb2FkZWQ6IGZhbHNlCiAgfTsKICB2YXIgaGFuZGxlUlQgPSBmdW5jdGlvbiBoYW5kbGVSVChyZWNlbnRUcmFkZSwgc3ltYm9sKSB7CiAgICByZXR1cm4gcmVjZW50VHJhZGUubWFwKGZ1bmN0aW9uIChfcmVmKSB7CiAgICAgIHZhciBfcmVmMiA9IF9zbGljZWRUb0FycmF5KF9yZWYsIDcpLAogICAgICAgIHRpY2tEaXJlY3Rpb24gPSBfcmVmMlswXSwKICAgICAgICBleGVjUHJpY2UgPSBfcmVmMlsxXSwKICAgICAgICBleGVjUXR5ID0gX3JlZjJbMl0sCiAgICAgICAgZXhlY1RpbWUgPSBfcmVmMlszXSwKICAgICAgICBzaWRlID0gX3JlZjJbNF0sCiAgICAgICAgZXhlY0lkID0gX3JlZjJbNV0sCiAgICAgICAgdHJhZGVUeXBlID0gX3JlZjJbNl07CiAgICAgIHJldHVybiB7CiAgICAgICAgZXhlY0lkOiBleGVjSWQsCiAgICAgICAgZXhlY1ByaWNlOiBleGVjUHJpY2UsCiAgICAgICAgZXhlY1F0eTogZXhlY1F0eSwKICAgICAgICBleGVjVGltZTogZXhlY1RpbWUsCiAgICAgICAgc2lkZTogc2lkZSA9PT0gJ2InID8gT3JkZXJBY3Rpb24uQlVZIDogT3JkZXJBY3Rpb24uU0VMTCwKICAgICAgICBzeW1ib2w6IHN5bWJvbCwKICAgICAgICB0aWNrRGlyZWN0aW9uOiBUSUNLX0RJUkVDVElPTl9NQVBbdGlja0RpcmVjdGlvbl0sCiAgICAgICAgdHJhZGVUeXBlOiB0cmFkZVR5cGUKICAgICAgfTsKICAgIH0pOwogIH07CiAgdmFyIHJlY2VudFRyYWRlU25hcHNob3RGbiA9IGZ1bmN0aW9uIHJlY2VudFRyYWRlU25hcHNob3RGbihyZWNlbnRUcmFkZSwgc3ltYm9sKSB7CiAgICByZWNlbnRUcmFkZVN0b3JlID0gewogICAgICBsaXN0OiBoYW5kbGVSVChyZWNlbnRUcmFkZSwgc3ltYm9sKSwKICAgICAgbG9hZGVkOiB0cnVlCiAgICB9OwogICAgcmV0dXJuIHJlY2VudFRyYWRlU3RvcmU7CiAgfTsKICB2YXIgcmVjZW50VHJhZGVEZWx0YUZuID0gZnVuY3Rpb24gcmVjZW50VHJhZGVEZWx0YUZuKHJlY2VudFRyYWRlLCBzeW1ib2wpIHsKICAgIHZhciBoYW5kbGVkUmVjZW50VHJhZGUgPSBoYW5kbGVSVChyZWNlbnRUcmFkZSwgc3ltYm9sKTsKICAgIHZhciBvbGRMZW4gPSByZWNlbnRUcmFkZVN0b3JlLmxpc3QubGVuZ3RoOwogICAgdmFyIG5ld0xlbiA9IGhhbmRsZWRSZWNlbnRUcmFkZS5sZW5ndGg7CiAgICBpZiAob2xkTGVuID09PSAwIHx8IG9sZExlbiA+IDAgJiYgRGF0ZS5wYXJzZShoYW5kbGVkUmVjZW50VHJhZGVbbmV3TGVuIC0gMV0uZXhlY1RpbWUpID49IERhdGUucGFyc2UocmVjZW50VHJhZGVTdG9yZS5saXN0WzBdLmV4ZWNUaW1lKSkgewogICAgICByZWNlbnRUcmFkZVN0b3JlLmxpc3QgPSBoYW5kbGVkUmVjZW50VHJhZGUucmV2ZXJzZSgpLmNvbmNhdChyZWNlbnRUcmFkZVN0b3JlLmxpc3QpOwogICAgfQogICAgaWYgKHJlY2VudFRyYWRlU3RvcmUubGlzdC5sZW5ndGggPiA2MCkgewogICAgICByZWNlbnRUcmFkZVN0b3JlLmxpc3QgPSByZWNlbnRUcmFkZVN0b3JlLmxpc3Quc2xpY2UoMCwgNjApOwogICAgfQogICAgcmVjZW50VHJhZGVTdG9yZS5sb2FkZWQgPSB0cnVlOwogICAgcmV0dXJuIHJlY2VudFRyYWRlU3RvcmU7CiAgfTsKICB2YXIgZ2V0UmVjZW50VHJhZGVTbmFwc2hvdCA9IGZ1bmN0aW9uIGdldFJlY2VudFRyYWRlU25hcHNob3QoKSB7CiAgICByZXR1cm4gcmVjZW50VHJhZGVTdG9yZTsKICB9OwogIHZhciByZWNlbnRUcmFkZUhhbmRsZXIgPSBmdW5jdGlvbiByZWNlbnRUcmFkZUhhbmRsZXIoc3ltYm9sLCByZXN1bHQpIHsKICAgIHZhciBfcmVjZW50VHJhZGVTdG9yZSRsaXM7CiAgICB2YXIgdHlwZSA9IHJlc3VsdC50eXBlLAogICAgICBkYXRhID0gcmVzdWx0LmRhdGE7CiAgICBpZiAodHlwZSA9PT0gJ3NuYXBzaG90JyAmJiBkYXRhLmQpIHsKICAgICAgcmV0dXJuIHJlY2VudFRyYWRlU25hcHNob3RGbihkYXRhLmQsIHN5bWJvbCk7CiAgICB9CiAgICBpZiAodHlwZSA9PT0gJ2RlbHRhJyAmJiBkYXRhLmQgJiYgZGF0YS5kLmxlbmd0aCAmJiAoKF9yZWNlbnRUcmFkZVN0b3JlJGxpcyA9IHJlY2VudFRyYWRlU3RvcmUubGlzdFswXSkgPT09IG51bGwgfHwgX3JlY2VudFRyYWRlU3RvcmUkbGlzID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfcmVjZW50VHJhZGVTdG9yZSRsaXMuc3ltYm9sKSA9PT0gZGF0YS5zKSB7CiAgICAgIC8vIHN5bWJvbCA9IGRhdGEucyDlkozorqLpmIXml7bmmK/kuIDoh7TnmoQKICAgICAgLy8gcmVjZW50VHJhZGVTdG9yZS5saXN0WzBdPy5zeW1ib2wgPT09IGRhdGEucyDnmoTpgLvovpHmmK/lnKjmjqjpgIHpmY3popHlkI7pooTpmLLlj6/og73kvJrlh7rnjrDnmoRzeW1ib2zliIfmjaLlr7zoh7TkuIrkuIDkuKrluIHlr7nnmoRkZWx0YeWMheaVsOaNrua3t+WFpQogICAgICByZXR1cm4gcmVjZW50VHJhZGVEZWx0YUZuKGRhdGEuZCwgc3ltYm9sKTsKICAgIH0KICAgIHJldHVybiBnZXRSZWNlbnRUcmFkZVNuYXBzaG90KCk7CiAgfTsKCiAgdmFyIGhhbmRsZVNpbmdsZUNhbmRsZSA9IGZ1bmN0aW9uIGhhbmRsZVNpbmdsZUNhbmRsZShyYXdPYmopIHsKICAgIHZhciByZXN1bHQgPSB7CiAgICAgIGNsb3NlOiAwLAogICAgICBjb25maXJtOiBmYWxzZSwKICAgICAgY3Jvc3Nfc2VxOiAwLAogICAgICBlbmQ6IDAsCiAgICAgIGhpZ2g6IDAsCiAgICAgIGxvdzogMCwKICAgICAgb3BlbjogMCwKICAgICAgcGVyaW9kOiAnMScsCiAgICAgIHN0YXJ0OiAwLAogICAgICB0aW1lc3RhbXA6IDAsCiAgICAgIHR1cm5vdmVyOiAwLAogICAgICB2b2x1bWU6IDAKICAgIH07CiAgICBPYmplY3QuZW50cmllcyhyYXdPYmopLm1hcChmdW5jdGlvbiAoX3JlZikgewogICAgICB2YXIgX3JlZjIgPSBfc2xpY2VkVG9BcnJheShfcmVmLCAyKSwKICAgICAgICBrZXkgPSBfcmVmMlswXSwKICAgICAgICB2YWx1ZSA9IF9yZWYyWzFdOwogICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiBrZXkgIT09ICdwZXJpb2QnICYmICFpc05hTigrdmFsdWUpKSB7CiAgICAgICAgcmVzdWx0W2tleV0gPSArdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZTsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gcmVzdWx0OwogIH07CiAgdmFyIGhhbmRsZUNhbmRsZU1zZyA9IGZ1bmN0aW9uIGhhbmRsZUNhbmRsZU1zZyhuYW1lU3BhY2UsIG9yaWdpbmFsQ2FuZGxlKSB7CiAgICB2YXIgcmVzdWx0ID0gW107CiAgICB2YXIgZGF0YSA9IG9yaWdpbmFsQ2FuZGxlLmRhdGE7CiAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkgewogICAgICByZXN1bHQgPSBkYXRhLm1hcChmdW5jdGlvbiAoaXRlbSkgewogICAgICAgIHJldHVybiBoYW5kbGVTaW5nbGVDYW5kbGUoaXRlbSk7CiAgICAgIH0pOwogICAgfQogICAgb3JpZ2luYWxDYW5kbGUuZGF0YSA9IHJlc3VsdDsKICAgIHJldHVybiBfb2JqZWN0U3ByZWFkMiQyKF9vYmplY3RTcHJlYWQyJDIoe30sIG9yaWdpbmFsQ2FuZGxlKSwge30sIHsKICAgICAgdG9waWM6IG5hbWVTcGFjZQogICAgfSk7CiAgfTsKCiAgdmFyIGhhbmRsZVNpbmdsZU1hcmtQcmljZSA9IGZ1bmN0aW9uIGhhbmRsZVNpbmdsZU1hcmtQcmljZShyYXdPYmopIHsKICAgIHZhciByZXN1bHQgPSB7CiAgICAgIGNsb3NlOiAwLAogICAgICBjb25maXJtOiAwLAogICAgICBoaWdoOiAwLAogICAgICBsb3c6IDAsCiAgICAgIG9wZW46IDAsCiAgICAgIHN0YXJ0OiAwLAogICAgICB2b2x1bWU6IDAKICAgIH07CiAgICBPYmplY3QuZW50cmllcyhyYXdPYmopLm1hcChmdW5jdGlvbiAoX3JlZikgewogICAgICB2YXIgX3JlZjIgPSBfc2xpY2VkVG9BcnJheShfcmVmLCAyKSwKICAgICAgICBrZXkgPSBfcmVmMlswXSwKICAgICAgICB2YWx1ZSA9IF9yZWYyWzFdOwogICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiAhaXNOYU4oK3ZhbHVlKSkgewogICAgICAgIHJlc3VsdFtrZXldID0gK3ZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7CiAgICAgIH0KICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdDsKICB9OwogIHZhciBoYW5kbGVNYXJrUHJpY2VNc2cgPSBmdW5jdGlvbiBoYW5kbGVNYXJrUHJpY2VNc2cobmFtZVNwYWNlLCBvcmlnaW5hbE1hcmtQcmljZSkgewogICAgdmFyIHJlc3VsdCA9IFtdOwogICAgdmFyIGRhdGEgPSBvcmlnaW5hbE1hcmtQcmljZS5kYXRhOwogICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHsKICAgICAgcmVzdWx0ID0gZGF0YS5tYXAoZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICByZXR1cm4gaGFuZGxlU2luZ2xlTWFya1ByaWNlKGl0ZW0pOwogICAgICB9KTsKICAgIH0KICAgIG9yaWdpbmFsTWFya1ByaWNlLmRhdGEgPSByZXN1bHQ7CiAgICByZXR1cm4gX29iamVjdFNwcmVhZDIkMihfb2JqZWN0U3ByZWFkMiQyKHt9LCBvcmlnaW5hbE1hcmtQcmljZSksIHt9LCB7CiAgICAgIHRvcGljOiBuYW1lU3BhY2UKICAgIH0pOwogIH07CgogIHZhciBoYW5kbGVDYWxjU2xpcHBhZ2UgPSBmdW5jdGlvbiBoYW5kbGVDYWxjU2xpcHBhZ2UoZGF0YSkgewogICAgdmFyIF9yZWYgPSBkYXRhIHx8IHt9LAogICAgICBnZXRPcmRlclF0eSA9IF9yZWYuZ2V0T3JkZXJRdHksCiAgICAgIG9yZGVyYm9vayA9IF9yZWYub3JkZXJib29rOwogICAgdmFyIF9yZWYyID0gZ2V0T3JkZXJRdHkgfHwge30sCiAgICAgIGxvbmdRdHlWYWx1ZSA9IF9yZWYyLmxvbmdRdHlWYWx1ZSwKICAgICAgc2hvcnRRdHlWYWx1ZSA9IF9yZWYyLnNob3J0UXR5VmFsdWUsCiAgICAgIGlzSW52ZXJzZVZhbHVlID0gX3JlZjIuaXNJbnZlcnNlVmFsdWU7CiAgICB2YXIgQnV5ID0gb3JkZXJib29rLkJ1eSwKICAgICAgU2VsbCA9IG9yZGVyYm9vay5TZWxsLAogICAgICBhc2sxUHJpY2UgPSBvcmRlcmJvb2suYXNrMVByaWNlLAogICAgICBiaWQxUHJpY2UgPSBvcmRlcmJvb2suYmlkMVByaWNlOwogICAgdmFyIGJ1eU9CTWFwID0gQnV5IHx8IHt9OwogICAgdmFyIHNlbGxPQk1hcCA9IFNlbGwgfHwge307CiAgICB2YXIgc2VsbE9CID0gT2JqZWN0LnZhbHVlcyhzZWxsT0JNYXApLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgcmV0dXJuIGEucHJpY2UgLSBiLnByaWNlOwogICAgfSk7IC8vIDwtLSBsb25nIOeci+i/meS4qu+8jHNlbGwgb2Lku47lsI/liLDlpKfmjpLliJcKICAgIHZhciBidXlPQiA9IE9iamVjdC52YWx1ZXMoYnV5T0JNYXApLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgcmV0dXJuIGIucHJpY2UgLSBhLnByaWNlOwogICAgfSk7IC8vIDwtLSBzaG9ydCDnnIvov5nkuKrvvIxidXkgb2Lku47lpKfliLDlsI/mjpLliJcKCiAgICAvLyDlj5ZvYua3seW6pu+8jOacgOWkmjIw5qGjCiAgICB2YXIgbWF4Q2FsY1NlbGxPQiA9IE1hdGgubWluKHNlbGxPQi5sZW5ndGgsIDIwKTsKICAgIHZhciBtYXhDYWxjQnV5T0IgPSBNYXRoLm1pbihidXlPQi5sZW5ndGgsIDIwKTsKCiAgICAvLyBsb25nU2xpcHBhZ2U6IOS5sOeahOa7keeCue+8jHNob3J0U2xpcHBhZ2XvvJrljZbnmoTmu5HngrnvvIwgZXhjZWVk77ya6LaF5Ye6b2Lmt7Hluqbov5Tlm550cnVlCiAgICB2YXIgcmVzdWx0ID0gewogICAgICBsb25nU2xpcHBhZ2U6IDAsCiAgICAgIHNob3J0U2xpcHBhZ2U6IDAsCiAgICAgIGV4Y2VlZDogZmFsc2UKICAgIH07CgogICAgLy8g5aaC5p6c55So5oi35pyJ6L6T5YWl5YC877yM5LiU5pyJb2LnmoTmg4XlhrXvvIzorqHnrpfkubDnmoTmu5HngrkKICAgIGlmIChsb25nUXR5VmFsdWUgPiAwICYmIHNlbGxPQi5sZW5ndGggPiAwKSB7CiAgICAgIHZhciBxdHkgPSBsb25nUXR5VmFsdWU7IC8vIOeUqOaIt+i+k+WFpeeahOaVsOmHjwogICAgICB2YXIgdmFsdWUgPSAwOyAvLyDph5Hpop0KICAgICAgdmFyIGZpbGxlZCA9IDA7IC8vIG9i5Y+v5Lul5Yy56YWN55qE5pWw6YePCiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wbHVzcGx1cwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1heENhbGNTZWxsT0IgJiYgcXR5ID4gMDsgaSsrKSB7CiAgICAgICAgdmFyIHByaWNlID0gc2VsbE9CW2ldLnByaWNlOwogICAgICAgIHZhciBzaXplID0gc2VsbE9CW2ldLnNpemU7CiAgICAgICAgaWYgKGlzSW52ZXJzZVZhbHVlKSBzaXplIC89IHByaWNlOwogICAgICAgIHZhciB0cmFkZVNpemUgPSBNYXRoLm1pbihzaXplLCBxdHkpOyAvLyDlj5blsI/lvZPliY1vYuaho+S9jeWSjOeUqOaIt+i+k+WFpeaVsOmHj+S9nOS4unRyYWRlU2l6ZQogICAgICAgIHZhbHVlICs9IHRyYWRlU2l6ZSAqIHByaWNlOyAvLyB0cmFkZVNpemUgKiDlvZPliY3moaPkvY3nmoTku7fmoLzvvIzlsLHmmK/lt7LljLnphY3nmoTph5Hpop0KICAgICAgICBmaWxsZWQgKz0gdHJhZGVTaXplOyAvLyDlt7LljLnphY3nmoTmlbDph48KICAgICAgICBxdHkgLT0gdHJhZGVTaXplOyAvLyDov5jmnKrljLnphY3nmoTmlbDph48KICAgICAgfQogICAgICAvLyDpooTkvLDmiJDkuqTlnYfku7fvvIznlKjlt7LljLnphY3nmoTph5Hpop0v5bey5Yy56YWN55qE5pWw6YePCiAgICAgIHZhciBhdmdGaWxsUHJpY2UgPSB2YWx1ZSAvIGZpbGxlZDsKCiAgICAgIC8vIOS5sOeahOa7keeCueiuoeeul+WFrOW8jyAoYWJzKOmihOS8sOaIkOS6pOWdh+S7tyAtIGFzazEpIC8gYXNrMSkgKiAxMDAKICAgICAgcmVzdWx0LmxvbmdTbGlwcGFnZSA9IE1hdGguYWJzKGF2Z0ZpbGxQcmljZSAtIGFzazFQcmljZSkgLyBhc2sxUHJpY2UgKiAxMDA7CiAgICAgIC8vIOWmguaenOi/mOacieacquWMuemFjeWujOeahOaVsOmHj++8jGV4Y2VlZOi/lOWbnnRydWUKICAgICAgaWYgKHF0eSA+IDApIHsKICAgICAgICByZXN1bHQuZXhjZWVkID0gdHJ1ZTsKICAgICAgfQogICAgfQogICAgLy8g5aaC5p6c55So5oi35pyJ6L6T5YWl5YC877yM5LiU5pyJb2LnmoTmg4XlhrXvvIzorqHnrpfljZbnmoTmu5HngrkKICAgIGlmIChzaG9ydFF0eVZhbHVlID4gMCAmJiBidXlPQi5sZW5ndGggPiAwKSB7CiAgICAgIHZhciBfcXR5ID0gc2hvcnRRdHlWYWx1ZTsgLy8g55So5oi36L6T5YWl55qE5pWw6YePCiAgICAgIHZhciBfdmFsdWUgPSAwOyAvLyDph5Hpop0KICAgICAgdmFyIF9maWxsZWQgPSAwOyAvLyBvYuWPr+S7peWMuemFjeeahOaVsOmHjwogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGx1c3BsdXMKICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IG1heENhbGNCdXlPQiAmJiBfcXR5ID4gMDsgX2krKykgewogICAgICAgIHZhciBfcHJpY2UgPSBidXlPQltfaV0ucHJpY2U7CiAgICAgICAgdmFyIF9zaXplID0gYnV5T0JbX2ldLnNpemU7CiAgICAgICAgaWYgKGlzSW52ZXJzZVZhbHVlKSBfc2l6ZSAvPSBfcHJpY2U7CiAgICAgICAgdmFyIF90cmFkZVNpemUgPSBNYXRoLm1pbihfc2l6ZSwgX3F0eSk7IC8vIOWPluWwj+W9k+WJjW9i5qGj5L2N5ZKM55So5oi36L6T5YWl5pWw6YeP5L2c5Li6dHJhZGVTaXplCiAgICAgICAgX3ZhbHVlICs9IF90cmFkZVNpemUgKiBfcHJpY2U7IC8vIHRyYWRlU2l6ZSAqIOW9k+WJjeaho+S9jeeahOS7t+agvO+8jOWwseaYr+W3suWMuemFjeeahOmHkeminQogICAgICAgIF9maWxsZWQgKz0gX3RyYWRlU2l6ZTsgLy8g5bey5Yy56YWN55qE5pWw6YePCiAgICAgICAgX3F0eSAtPSBfdHJhZGVTaXplOyAvLyDov5jmnKrljLnphY3nmoTmlbDph48KICAgICAgfQogICAgICAvLyDpooTkvLDmiJDkuqTlnYfku7fvvIznlKjlt7LljLnphY3nmoTph5Hpop0v5bey5Yy56YWN55qE5pWw6YePCiAgICAgIHZhciBfYXZnRmlsbFByaWNlID0gX3ZhbHVlIC8gX2ZpbGxlZDsKCiAgICAgIC8vIOWNlueahOa7keeCueiuoeeul+WFrOW8jyAoYWJzKOmihOS8sOaIkOS6pOWdh+S7tyAtIGJpZDEpIC8gYmlkMSkgKiAxMDAKICAgICAgcmVzdWx0LnNob3J0U2xpcHBhZ2UgPSBNYXRoLmFicyhfYXZnRmlsbFByaWNlIC0gYmlkMVByaWNlKSAvIGJpZDFQcmljZSAqIDEwMDsKICAgICAgLy8g5aaC5p6c6L+Y5pyJ5pyq5Yy56YWN5a6M55qE5pWw6YeP77yMZXhjZWVk6L+U5ZuedHJ1ZQogICAgICBpZiAoX3F0eSA+IDApIHsKICAgICAgICByZXN1bHQuZXhjZWVkID0gdHJ1ZTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9OwoKICAvKioKICAgKiDlpJogc3ltYm9sIOeKtuaAgeeuoeeQhgogICAqLwogIHZhciBzdGF0ZU1hcEZvck9wdGlvbiA9IHt9OwogIC8qKgogICAqIOWIneWni+WMlum7mOiupOeKtuaAgQogICAqLwogIHZhciBjcmVhdGVJbml0aWFsU3RhdGUgPSBmdW5jdGlvbiBjcmVhdGVJbml0aWFsU3RhdGUoKSB7CiAgICByZXR1cm4gewogICAgICBsb2FkZWQ6IGZhbHNlLAogICAgICBzZWxsOiBbXSwKICAgICAgYXNrMUlkOiAwLAogICAgICBidXk6IFtdLAogICAgICBiaWQxSWQ6IDAsCiAgICAgIGFzazFQcmljZTogMCwKICAgICAgYmlkMVByaWNlOiAwLAogICAgICBkZXB0aEdyb3VwZWRCdXlMaXN0OiBbXSwKICAgICAgZGVwdGhHcm91cGVkU2VsbExpc3Q6IFtdLAogICAgICBzeW1ib2xOYW1lOiAnJywKICAgICAgc2VxOiAtMSwKICAgICAgdGltZXN0YW1wOiAwLAogICAgICB0b3RhbEJ1eVF0eTogMCwKICAgICAgdG90YWxTZWxsUXR5OiAwCiAgICB9OwogIH07CiAgLyoqCiAgICog6I635Y+W5oyH5a6aIHN5bWJvbCDnmoTnirbmgIHvvIzlpoLmnpzkuI3lrZjlnKjliJnliJvlu7oKICAgKi8KICB2YXIgZ2V0U3RhdGUgPSBmdW5jdGlvbiBnZXRTdGF0ZShzeW1ib2wpIHsKICAgIGlmICghc3RhdGVNYXBGb3JPcHRpb25bc3ltYm9sXSkgewogICAgICBzdGF0ZU1hcEZvck9wdGlvbltzeW1ib2xdID0gY3JlYXRlSW5pdGlhbFN0YXRlKCk7CiAgICB9CiAgICByZXR1cm4gc3RhdGVNYXBGb3JPcHRpb25bc3ltYm9sXTsKICB9OwogIC8qKgogICAqIOiuvue9ruaMh+WumiBzeW1ib2wg55qE54q25oCBCiAgICovCiAgdmFyIHNldFN0YXRlID0gZnVuY3Rpb24gc2V0U3RhdGUoc3ltYm9sLCBuZXdTdGF0ZSkgewogICAgc3RhdGVNYXBGb3JPcHRpb25bc3ltYm9sXSA9IG5ld1N0YXRlOwogIH07CiAgdmFyIGZpeEJ1eUxpc3QgPSBmdW5jdGlvbiBmaXhCdXlMaXN0KGJ1eUxpc3QpIHsKICAgIHZhciBiaWRJZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogMDsKICAgIHdoaWxlIChidXlMaXN0ICYmIGJpZElkICE9PSAwICYmIGJ1eUxpc3QubGVuZ3RoID4gMCAmJiBidXlMaXN0WzBdLklkID4gYmlkSWQpIGJ1eUxpc3Quc2hpZnQoKTsKICAgIHJldHVybiBidXlMaXN0OwogIH07CiAgdmFyIGZpeFNlbGxMaXN0ID0gZnVuY3Rpb24gZml4U2VsbExpc3Qoc2VsbExpc3QpIHsKICAgIHZhciBhc2tJZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogMDsKICAgIHdoaWxlIChzZWxsTGlzdCAmJiBhc2tJZCAhPT0gMCAmJiBzZWxsTGlzdC5sZW5ndGggPiAwICYmIHNlbGxMaXN0W3NlbGxMaXN0Lmxlbmd0aCAtIDFdLklkIDwgYXNrSWQpIHsKICAgICAgc2VsbExpc3QucG9wKCk7CiAgICB9CiAgICByZXR1cm4gc2VsbExpc3Q7CiAgfTsKICB2YXIgc29ydE9iID0gZnVuY3Rpb24gc29ydE9iKGEsIGIpIHsKICAgIHJldHVybiBiLklkIC0gYS5JZDsKICB9OwogIHZhciBjYWxjVG90YWwgPSBmdW5jdGlvbiBjYWxjVG90YWwocHJldiwgY3VyKSB7CiAgICByZXR1cm4gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShwcmV2KSwgW19vYmplY3RTcHJlYWQyJDIoX29iamVjdFNwcmVhZDIkMih7fSwgY3VyKSwge30sIHsKICAgICAgdG90YWxRdHk6IG5ldyBEZWNpbWFsKGN1ci5xdHkpLmFkZChwcmV2Lmxlbmd0aCA/IHByZXZbcHJldi5sZW5ndGggLSAxXS50b3RhbFF0eSB8fCAwIDogMCkudG9OdW1iZXIoKQogICAgfSldKTsKICB9OwogIHZhciBoYW5kbGVPQkl0ZW0gPSBmdW5jdGlvbiBoYW5kbGVPQkl0ZW0ob2JJdGVtKSB7CiAgICB2YXIgX29iSXRlbSA9IF9zbGljZWRUb0FycmF5KG9iSXRlbSwgMiksCiAgICAgIHByaWNlID0gX29iSXRlbVswXSwKICAgICAgcXR5ID0gX29iSXRlbVsxXTsKICAgIHJldHVybiB7CiAgICAgIElkOiBOdW1iZXIocHJpY2UpLAogICAgICBwcmljZTogcHJpY2UsCiAgICAgIHF0eTogcXR5LAogICAgICB0b3RhbFF0eTogMAogICAgfTsKICB9OwogIHZhciBoYW5kbGVPQiA9IGZ1bmN0aW9uIGhhbmRsZU9CKCkgewogICAgdmFyIG9yZGVyYm9vayA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogewogICAgICBiOiBbXSwKICAgICAgYTogW10KICAgIH07CiAgICB2YXIgX29yZGVyYm9vayRiID0gb3JkZXJib29rLmIsCiAgICAgIGIgPSBfb3JkZXJib29rJGIgPT09IHZvaWQgMCA/IFtdIDogX29yZGVyYm9vayRiLAogICAgICBfb3JkZXJib29rJGEgPSBvcmRlcmJvb2suYSwKICAgICAgYSA9IF9vcmRlcmJvb2skYSA9PT0gdm9pZCAwID8gW10gOiBfb3JkZXJib29rJGE7CiAgICB2YXIgYnV5TGlzdCA9IGIubWFwKGhhbmRsZU9CSXRlbSk7CiAgICB2YXIgc2VsbExpc3QgPSBhLm1hcChoYW5kbGVPQkl0ZW0pOwogICAgcmV0dXJuIFtidXlMaXN0LCBzZWxsTGlzdF07CiAgfTsKICB2YXIgc2V0QXNrQmlkUHJpY2UgPSBmdW5jdGlvbiBzZXRBc2tCaWRQcmljZSgpIHsKICAgIHZhciBvcmRlcmJvb2sgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHsKICAgICAgYjogW10sCiAgICAgIGE6IFtdCiAgICB9OwogICAgdmFyIHByaWNlU2NhbGUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDsKICAgIHZhciBzdGF0ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkOwogICAgdmFyIF9vcmRlcmJvb2skYTIgPSBvcmRlcmJvb2suYTEsCiAgICAgIGExID0gX29yZGVyYm9vayRhMiA9PT0gdm9pZCAwID8gJzAnIDogX29yZGVyYm9vayRhMiwKICAgICAgX29yZGVyYm9vayRiMiA9IG9yZGVyYm9vay5iMSwKICAgICAgYjEgPSBfb3JkZXJib29rJGIyID09PSB2b2lkIDAgPyAnMCcgOiBfb3JkZXJib29rJGIyOwogICAgc3RhdGUuYXNrMVByaWNlID0gTnVtYmVyKGExKTsKICAgIHZhciBhc2sxSWQgPSBuZXcgRGVjaW1hbChhMSkubXVsKHByaWNlU2NhbGUpLnRvTnVtYmVyKCk7CiAgICBzdGF0ZS5hc2sxSWQgPSBhc2sxSWQ7CiAgICBzdGF0ZS5iaWQxUHJpY2UgPSBOdW1iZXIoYjEpOwogICAgdmFyIGJpZDFJZCA9IG5ldyBEZWNpbWFsKGIxKS5tdWwocHJpY2VTY2FsZSkudG9OdW1iZXIoKTsKICAgIHN0YXRlLmJpZDFJZCA9IGJpZDFJZDsKICB9OwogIHZhciBnZXRUb3RhbENhbGN1bGF0ZWRBbmRTb3J0ZWRMaXN0ID0gZnVuY3Rpb24gZ2V0VG90YWxDYWxjdWxhdGVkQW5kU29ydGVkTGlzdChidXlMaXN0LCBzZWxsTGlzdCkgewogICAgdmFyIGJpZDFJZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogMDsKICAgIHZhciBhc2sxSWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMyAmJiBhcmd1bWVudHNbM10gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1szXSA6IDA7CiAgICB2YXIgbmV3QnV5TGlzdCA9IGZpeEJ1eUxpc3QoYnV5TGlzdC5zb3J0KHNvcnRPYiksIGJpZDFJZCk7CiAgICB2YXIgbmV3U2VsbExpc3QgPSBmaXhTZWxsTGlzdChzZWxsTGlzdC5zb3J0KHNvcnRPYiksIGFzazFJZCk7CiAgICBuZXdCdXlMaXN0ID0gbmV3QnV5TGlzdC5yZWR1Y2UoY2FsY1RvdGFsLCBbXSk7CiAgICBuZXdTZWxsTGlzdCA9IG5ld1NlbGxMaXN0LnJlZHVjZVJpZ2h0KGNhbGNUb3RhbCwgW10pLnJldmVyc2UoKTsKICAgIHJldHVybiBbbmV3QnV5TGlzdCwgbmV3U2VsbExpc3RdOwogIH07CiAgdmFyIG9yZGVyQm9va1NuYXBzaG90Rm4gPSBmdW5jdGlvbiBvcmRlckJvb2tTbmFwc2hvdEZuKCkgewogICAgdmFyIG9yZGVyYm9vayA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogewogICAgICBiOiBbXSwKICAgICAgYTogW10sCiAgICAgIGExOiAnMCcsCiAgICAgIGIxOiAnMCcsCiAgICAgIGNzOiAwLAogICAgICB0czogMAogICAgfTsKICAgIHZhciBzeW1ib2wgPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDsKICAgIHZhciBjcyA9IG9yZGVyYm9vay5jcywKICAgICAgdHMgPSBvcmRlcmJvb2sudHM7CiAgICB2YXIgX2hhbmRsZU9CID0gaGFuZGxlT0Iob3JkZXJib29rKSwKICAgICAgX2hhbmRsZU9CMiA9IF9zbGljZWRUb0FycmF5KF9oYW5kbGVPQiwgMiksCiAgICAgIGJ1eUxpc3QgPSBfaGFuZGxlT0IyWzBdLAogICAgICBzZWxsTGlzdCA9IF9oYW5kbGVPQjJbMV07CiAgICB2YXIgX2dldFRvdGFsQ2FsY3VsYXRlZEFuID0gZ2V0VG90YWxDYWxjdWxhdGVkQW5kU29ydGVkTGlzdChidXlMaXN0LCBzZWxsTGlzdCk7CiAgICB2YXIgX2dldFRvdGFsQ2FsY3VsYXRlZEFuMiA9IF9zbGljZWRUb0FycmF5KF9nZXRUb3RhbENhbGN1bGF0ZWRBbiwgMik7CiAgICBidXlMaXN0ID0gX2dldFRvdGFsQ2FsY3VsYXRlZEFuMlswXTsKICAgIHNlbGxMaXN0ID0gX2dldFRvdGFsQ2FsY3VsYXRlZEFuMlsxXTsKICAgIHZhciBhc2sxUHJpY2UgPSBOdW1iZXIob3JkZXJib29rLmExKTsKICAgIHZhciBiaWQxUHJpY2UgPSBOdW1iZXIob3JkZXJib29rLmIxKTsKICAgIHZhciBuZXdTdGF0ZSA9IHsKICAgICAgbG9hZGVkOiB0cnVlLAogICAgICBzZWxsOiBzZWxsTGlzdCwKICAgICAgYXNrMUlkOiBhc2sxUHJpY2UsCiAgICAgIGFzazFQcmljZTogYXNrMVByaWNlLAogICAgICBidXk6IGJ1eUxpc3QsCiAgICAgIGJpZDFJZDogYmlkMVByaWNlLAogICAgICBiaWQxUHJpY2U6IGJpZDFQcmljZSwKICAgICAgZGVwdGhHcm91cGVkQnV5TGlzdDogW10sCiAgICAgIGRlcHRoR3JvdXBlZFNlbGxMaXN0OiBbXSwKICAgICAgc3ltYm9sTmFtZTogc3ltYm9sLAogICAgICBzZXE6IGNzIHx8IC0xLAogICAgICAvLyBzeW1ib2xJZAogICAgICAvLyBxdW90ZUNvaW4KICAgICAgdGltZXN0YW1wOiB0cyB8fCAwLAogICAgICB0b3RhbEJ1eVF0eTogYnV5TGlzdC5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cikgewogICAgICAgIHJldHVybiBwcmV2ICsgTnVtYmVyKGN1ci5xdHkpOwogICAgICB9LCAwKSwKICAgICAgdG90YWxTZWxsUXR5OiBzZWxsTGlzdC5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cikgewogICAgICAgIHJldHVybiBwcmV2ICsgTnVtYmVyKGN1ci5xdHkpOwogICAgICB9LCAwKQogICAgfTsKICAgIC8vIOabtOaWsOeKtuaAgeWIsCBzdGF0ZU1hcEZvck9wdGlvbgogICAgc2V0U3RhdGUoc3ltYm9sLCBuZXdTdGF0ZSk7CiAgICByZXR1cm4gc3RhdGVNYXBGb3JPcHRpb247CiAgfTsKICB2YXIgb3JkZXJCb29rRGVsdGFGbiA9IGZ1bmN0aW9uIG9yZGVyQm9va0RlbHRhRm4oKSB7CiAgICB2YXIgb3JkZXJib29rID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7CiAgICAgIGI6IFtdLAogICAgICBhOiBbXSwKICAgICAgYTE6ICcwJywKICAgICAgYjE6ICcwJwogICAgfTsKICAgIHZhciBzeW1ib2wgPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDsKICAgIC8vIOiOt+WPluivpSBzeW1ib2wg55qE5b2T5YmN54q25oCBCiAgICB2YXIgY3VycmVudFN0YXRlID0gZ2V0U3RhdGUoc3ltYm9sKTsKICAgIHNldEFza0JpZFByaWNlKG9yZGVyYm9vaywgMSwgY3VycmVudFN0YXRlKTsKICAgIHZhciBfaGFuZGxlT0IzID0gaGFuZGxlT0Iob3JkZXJib29rKSwKICAgICAgX2hhbmRsZU9CNCA9IF9zbGljZWRUb0FycmF5KF9oYW5kbGVPQjMsIDIpLAogICAgICBidXlMaXN0ID0gX2hhbmRsZU9CNFswXSwKICAgICAgc2VsbExpc3QgPSBfaGFuZGxlT0I0WzFdOwogICAgdmFyIGJ1eSA9IGN1cnJlbnRTdGF0ZS5idXksCiAgICAgIHNlbGwgPSBjdXJyZW50U3RhdGUuc2VsbDsKICAgIGJ1eUxpc3QuZm9yRWFjaChmdW5jdGlvbiAobmV3SXRlbSkgewogICAgICB2YXIgdGFyZ2V0SW5kZXggPSBidXkuZmluZEluZGV4KGZ1bmN0aW9uIChzdGF0ZUl0ZW0pIHsKICAgICAgICByZXR1cm4gbmV3SXRlbS5JZCA9PT0gc3RhdGVJdGVtLklkOwogICAgICB9KTsKICAgICAgaWYgKHRhcmdldEluZGV4ID09PSAtMSkgewogICAgICAgIC8vIOayoeWMuemFjeWIsAogICAgICAgIGlmIChOdW1iZXIobmV3SXRlbS5xdHkpICE9PSAwKSB7CiAgICAgICAgICAvLyBzaXpl5LiN5Li6MCA9PiDmlrDlop4KICAgICAgICAgIGJ1eS5wdXNoKG5ld0l0ZW0pOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyDljLnphY3liLAKICAgICAgICBpZiAoTnVtYmVyKG5ld0l0ZW0ucXR5KSA9PT0gMCkgewogICAgICAgICAgLy8gc2l6ZeS4ujAgPT4g5Yig6ZmkCiAgICAgICAgICBidXkuc3BsaWNlKHRhcmdldEluZGV4LCAxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gc2l6ZeS4jeS4ujAgPT4g5pu/5o2iCiAgICAgICAgICBidXkuc3BsaWNlKHRhcmdldEluZGV4LCAxLCBuZXdJdGVtKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0pOwogICAgc2VsbExpc3QuZm9yRWFjaChmdW5jdGlvbiAobmV3SXRlbSkgewogICAgICB2YXIgdGFyZ2V0SW5kZXggPSBzZWxsLmZpbmRJbmRleChmdW5jdGlvbiAoc3RhdGVJdGVtKSB7CiAgICAgICAgcmV0dXJuIG5ld0l0ZW0uSWQgPT09IHN0YXRlSXRlbS5JZDsKICAgICAgfSk7CiAgICAgIGlmICh0YXJnZXRJbmRleCA9PT0gLTEpIHsKICAgICAgICAvLyDmsqHljLnphY3liLAKICAgICAgICBpZiAoTnVtYmVyKG5ld0l0ZW0ucXR5KSAhPT0gMCkgewogICAgICAgICAgLy8gc2l6ZeS4jeS4ujAgPT4g5paw5aKeCiAgICAgICAgICBzZWxsLnB1c2gobmV3SXRlbSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIOWMuemFjeWIsAogICAgICAgIGlmIChOdW1iZXIobmV3SXRlbS5xdHkpID09PSAwKSB7CiAgICAgICAgICAvLyBzaXpl5Li6MCA9PiDliKDpmaQKICAgICAgICAgIHNlbGwuc3BsaWNlKHRhcmdldEluZGV4LCAxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gc2l6ZeS4jeS4ujAgPT4g5pu/5o2iCiAgICAgICAgICBzZWxsLnNwbGljZSh0YXJnZXRJbmRleCwgMSwgbmV3SXRlbSk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICAgIHZhciBfZ2V0VG90YWxDYWxjdWxhdGVkQW4zID0gZ2V0VG90YWxDYWxjdWxhdGVkQW5kU29ydGVkTGlzdChjdXJyZW50U3RhdGUuYnV5LCBjdXJyZW50U3RhdGUuc2VsbCwgY3VycmVudFN0YXRlLmJpZDFJZCwgY3VycmVudFN0YXRlLmFzazFJZCk7CiAgICB2YXIgX2dldFRvdGFsQ2FsY3VsYXRlZEFuNCA9IF9zbGljZWRUb0FycmF5KF9nZXRUb3RhbENhbGN1bGF0ZWRBbjMsIDIpOwogICAgY3VycmVudFN0YXRlLmJ1eSA9IF9nZXRUb3RhbENhbGN1bGF0ZWRBbjRbMF07CiAgICBjdXJyZW50U3RhdGUuc2VsbCA9IF9nZXRUb3RhbENhbGN1bGF0ZWRBbjRbMV07CiAgICB2YXIgYXNrMVByaWNlID0gTnVtYmVyKG9yZGVyYm9vay5hMSk7CiAgICB2YXIgYmlkMVByaWNlID0gTnVtYmVyKG9yZGVyYm9vay5iMSk7CiAgICBpZiAoYXNrMVByaWNlKSB7CiAgICAgIGN1cnJlbnRTdGF0ZS5hc2sxUHJpY2UgPSBhc2sxUHJpY2U7CiAgICB9CiAgICBpZiAoYmlkMVByaWNlKSB7CiAgICAgIGN1cnJlbnRTdGF0ZS5iaWQxUHJpY2UgPSBiaWQxUHJpY2U7CiAgICB9CiAgICBjdXJyZW50U3RhdGUuc3ltYm9sTmFtZSA9IHN5bWJvbDsKICAgIC8vIOabtOaWsOaAu+mHjwogICAgY3VycmVudFN0YXRlLnRvdGFsQnV5UXR5ID0gY3VycmVudFN0YXRlLmJ1eS5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cikgewogICAgICByZXR1cm4gcHJldiArIE51bWJlcihjdXIucXR5KTsKICAgIH0sIDApOwogICAgY3VycmVudFN0YXRlLnRvdGFsU2VsbFF0eSA9IGN1cnJlbnRTdGF0ZS5zZWxsLnJlZHVjZShmdW5jdGlvbiAocHJldiwgY3VyKSB7CiAgICAgIHJldHVybiBwcmV2ICsgTnVtYmVyKGN1ci5xdHkpOwogICAgfSwgMCk7CiAgICByZXR1cm4gc3RhdGVNYXBGb3JPcHRpb247CiAgfTsKICB2YXIgb3JkZXJCb29rT3B0aW9uSGFuZGxlciA9IGZ1bmN0aW9uIG9yZGVyQm9va09wdGlvbkhhbmRsZXIobmFtZVNwYWNlLCByZXN1bHQpIHsKICAgIHZhciB0eXBlID0gcmVzdWx0LnR5cGUsCiAgICAgIGRhdGEgPSByZXN1bHQuZGF0YTsKICAgIHJldHVybiB0eXBlID09PSAnc25hcHNob3QnID8gb3JkZXJCb29rU25hcHNob3RGbihkYXRhLCBuYW1lU3BhY2UpIDogb3JkZXJCb29rRGVsdGFGbihkYXRhLCBuYW1lU3BhY2UpOwogIH07CgogIC8qKgogICAqIE1UNSBPcmRlckJvb2sgSGFuZGxlciAtIOWOn+agt+i/lOWbnuaVsOaNrgogICAqIOacjeWKoeerr+i/lOWbnuagvOW8j++8mgogICAqIHsKICAgKiAgICJzIjogIlhBVVVTRCIsCiAgICogICAiYiI6IFtbIjExODg0NS45MCIsICIwLjAwMSIsICIxMjM0Il1dLAogICAqICAgImEiOiBbWyIxMTg4NTQuMDAiLCAiNy40MDEiLCAiMzI0MzIiXV0KICAgKiB9CiAgICovCiAgLyoqCiAgICogTVQ1IE9yZGVyQm9vayDlpITnkIblmaggLSDnm7TmjqXov5Tlm57ljp/lp4vmlbDmja4KICAgKiDkuIDmrKHlj6rorqLpmIXkuIDkuKogc3ltYm9s77yM5peg6ZyA57u05oqk5aSaIHN5bWJvbCDnirbmgIEKICAgKi8KICB2YXIgb3JkZXJCb29rTXQ1SGFuZGxlciA9IGZ1bmN0aW9uIG9yZGVyQm9va010NUhhbmRsZXIobmFtZVNwYWNlLCByZXN1bHQpIHsKICAgIC8vIOebtOaOpei/lOWbnuWOn+Wni+aVsOaNru+8jOS4jeWBmuS7u+S9leWkhOeQhgogICAgcmV0dXJuIChyZXN1bHQgPT09IG51bGwgfHwgcmVzdWx0ID09PSB2b2lkIDAgPyB2b2lkIDAgOiByZXN1bHQuZGF0YSkgfHwge307CiAgfTsKCiAgdmFyIGFscGhhSW5zdHJ1bWVudEtleU1hcCA9IHsKICAgIHN5bWJvbDogJ3N5bWJvbCcsCiAgICBjaGFpbkNvZGU6ICdjaGFpbkNvZGUnLAogICAgYWRkcmVzczogJ2FkZHJlc3MnLAogICAgcHJpY2U6ICdwcmljZScsCiAgICBwcmljZVRpbWVNUzogJ3ByaWNlVGltZU1TJywKICAgIGNoYW5nZTI0aDogJ2NoYW5nZTI0aCcsCiAgICBjaGFuZ2UxaDogJ2NoYW5nZTFoJywKICAgIHZvbDI0aDogJ3ZvbDI0aCcKICB9OwogIHZhciBhbHBoYU51bWJlcktleSA9IHsKICAgIHByaWNlOiAncHJpY2UnLAogICAgcHJpY2VUaW1lTVM6ICdwcmljZVRpbWVNUycsCiAgICBjaGFuZ2UyNGg6ICdjaGFuZ2UyNGgnLAogICAgY2hhbmdlMWg6ICdjaGFuZ2UxaCcsCiAgICB2b2wyNGg6ICd2b2wyNGgnCiAgfTsKICB2YXIgaGFuZGxlSW5zdHJ1bWVudCA9IGZ1bmN0aW9uIGhhbmRsZUluc3RydW1lbnQoaW5zdHJ1bWVudCkgewogICAgdmFyIHJlc3VsdCA9IHsKICAgICAgc3ltYm9sOiAnJwogICAgfTsKICAgIE9iamVjdC5lbnRyaWVzKGluc3RydW1lbnQpLmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHsKICAgICAgdmFyIF9yZWYyID0gX3NsaWNlZFRvQXJyYXkoX3JlZiwgMiksCiAgICAgICAga2V5ID0gX3JlZjJbMF0sCiAgICAgICAgdmFsdWUgPSBfcmVmMlsxXTsKICAgICAgaWYgKGFscGhhSW5zdHJ1bWVudEtleU1hcFtrZXldKSB7CiAgICAgICAgcmVzdWx0W2FscGhhSW5zdHJ1bWVudEtleU1hcFtrZXldXSA9IGFscGhhTnVtYmVyS2V5W2tleV0gPyB0b051bWJlcih2YWx1ZSkgOiB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXN1bHRba2V5XSA9IHZhbHVlOwogICAgICB9CiAgICB9KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfTsKICAvLyBOT1RJQ0U6IOS/ruaUueaVsOaNrue7k+aehO+8mk1BUFBJTkflr7nosaHlrZjlgqjvvIzlj6/ku6XlrZjlgqjlpJrkuKrvvIzpmLLmraLorqLpmIXlpJrkuKppbnN0cnVtZW505pe25a+86Ie05pWw5o2u5byC5bi4CiAgLy8gaW5zdHJ1bWVudF9pbmZvX3YzLmFsbCDlop7ph4/lpITnkIYKICB2YXIgaW5zdHJ1bWVudExpc3QgPSBbXTsKICAvLyDlhajph4/mlbDmja4g5aSE55CGCiAgdmFyIGluc3RydW1lbnRBbGxTbmFwc2hvdEZuID0gZnVuY3Rpb24gaW5zdHJ1bWVudEFsbFNuYXBzaG90Rm4oaW5zdHJ1bWVudHMpIHsKICAgIHZhciByZXN1bHRMaXN0ID0gW107CiAgICBpbnN0cnVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgIHJlc3VsdExpc3QucHVzaChoYW5kbGVJbnN0cnVtZW50KGl0ZW0pKTsKICAgIH0pOwogICAgLy8g5YWo6YeP5pu05pawCiAgICBpbnN0cnVtZW50TGlzdCA9IHJlc3VsdExpc3Q7CiAgICByZXR1cm4gaW5zdHJ1bWVudExpc3Q7CiAgfTsKICAvLyDlop7ph4/mlbDmja4g5aSE55CGCiAgdmFyIGluc3RydW1lbnRBbGxEZXRhbEZuID0gZnVuY3Rpb24gaW5zdHJ1bWVudEFsbERldGFsRm4oaW5zdHJ1bWVudHMpIHsKICAgIGluc3RydW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGlucykgewogICAgICB2YXIgaW5zSXRlbSA9IGhhbmRsZUluc3RydW1lbnQoaW5zKTsKICAgICAgLy8g5piv5LiN5piv6ZyA6KaB6ICD6JmR5L2/55SoYWRkcmVzcyDvvJ/vvJ8KICAgICAgdmFyIHRhcmdldEluZGV4ID0gaW5zdHJ1bWVudExpc3QuZmluZEluZGV4KGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgcmV0dXJuIGl0ZW0uYWRkcmVzcyA9PT0gaW5zSXRlbS5hZGRyZXNzOwogICAgICB9KTsKICAgICAgaWYgKHRhcmdldEluZGV4ID4gLTEpIHsKICAgICAgICAvLyDlrZjlnKjlkIjlubYKICAgICAgICB2YXIgdGFyZ2VJbnMgPSBpbnN0cnVtZW50TGlzdFt0YXJnZXRJbmRleF07CiAgICAgICAgaW5zdHJ1bWVudExpc3RbdGFyZ2V0SW5kZXhdID0gX29iamVjdFNwcmVhZDIkMihfb2JqZWN0U3ByZWFkMiQyKHt9LCB0YXJnZUlucyksIGluc0l0ZW0pOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIOS4jeWtmOWcqCDmlrDlop4KICAgICAgICBpbnN0cnVtZW50TGlzdC5wdXNoKGluc0l0ZW0pOwogICAgICB9CiAgICB9KTsKICAgIHJldHVybiBpbnN0cnVtZW50TGlzdDsKICB9OwogIC8vIGV4cG9ydCBjb25zdCBnZXRJbnN0cnVtZW50QWxsU25hcFNob3QgPSAoKTogSUluc3RydW1lbnRbXSA9PiBpbnN0cnVtZW50TGlzdDsKCiAgLy8gSW5zdHJ1bWVudEluZm9BbGwg5pS55Li65aKe6YeP5aSE55CGCiAgdmFyIGhhbmRsZUFscGhhQWxsU3ltYm9sID0gZnVuY3Rpb24gaGFuZGxlQWxwaGFBbGxTeW1ib2wob3JpZ2luYWxNZXNzYWdlKSB7CiAgICB2YXIgZGF0YSA9IG9yaWdpbmFsTWVzc2FnZS5kYXRhLAogICAgICB0eXBlID0gb3JpZ2luYWxNZXNzYWdlLnR5cGU7CiAgICAvLyByZXNldOehruiupAogICAgaWYgKHR5cGUgPT09ICdzbmFwc2hvdCcgfHwgdHlwZSA9PT0gJ3Jlc2V0JykgewogICAgICBvcmlnaW5hbE1lc3NhZ2UuZGF0YSA9IGluc3RydW1lbnRBbGxTbmFwc2hvdEZuKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgb3JpZ2luYWxNZXNzYWdlLmRhdGEgPSBpbnN0cnVtZW50QWxsRGV0YWxGbihkYXRhKTsKICAgIH0KICAgIHJldHVybiBvcmlnaW5hbE1lc3NhZ2U7CiAgfTsKCiAgdmFyIHRvcGljU2VuZEluZm8gPSB7CiAgICBERUZBVUxUX1RIUk9UVExFX1RJTUU6IDUwLAogICAgdGhyb3R0bGVNYXA6IHsKICAgICAgLy8g6IqC5rWB5Ye95pWwCiAgICB9LAogICAgZ2V0VGhyb3R0bGVQb3N0OiBmdW5jdGlvbiBnZXRUaHJvdHRsZVBvc3QodG9waWMpIHsKICAgICAgaWYgKCF0aGlzLnRocm90dGxlTWFwW3RvcGljXSkgewogICAgICAgIC8vIOWIm+W7uuS4gOS4quaWsOeahOiKgua1geWHveaVsAogICAgICAgIHRoaXMudGhyb3R0bGVNYXBbdG9waWNdID0gbG9kYXNoX3Rocm90dGxlKGZ1bmN0aW9uIChtc2cpIHsKICAgICAgICAgIHNlbGYucG9zdE1lc3NhZ2UobXNnKTsKICAgICAgICB9LCB0b3BpY1NlbmRJbmZvLkRFRkFVTFRfVEhST1RUTEVfVElNRSwgewogICAgICAgICAgbGVhZGluZzogdHJ1ZSwKICAgICAgICAgIHRyYWlsaW5nOiB0cnVlCiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMudGhyb3R0bGVNYXBbdG9waWNdOwogICAgfSwKICAgIHRocm90dGxlUG9zdE1lc3NhZ2U6IGZ1bmN0aW9uIHRocm90dGxlUG9zdE1lc3NhZ2UodG9waWMsIG1zZykgewogICAgICB2YXIgdGhyb3R0bGVQb3N0ID0gdGhpcy5nZXRUaHJvdHRsZVBvc3QodG9waWMpOwogICAgICB0aHJvdHRsZVBvc3QobXNnKTsKICAgIH0KICB9OwogIHZhciB3c0luc3RhbmNlID0gbnVsbDsKICB2YXIgb3BlblByaWNlTGlzdCA9IHt9OwogIC8vIOS/neWtmOS4u+e6v+eoi+S8oOi/h+adpeeahOaVsOaNrgogIHZhciBtdDVUaWNrZXJzQWxsTWFwID0ge307CiAgLy8g5L+d5a2Y5q+P5LiqdG9waWPnmoToioLmtYF0aW1l6YWN572uCiAgdmFyIHRvcGljVGhyb3R0bGVDb25maWcgPSBuZXcgTWFwKCk7CiAgdmFyIHRocm90dGxlRnVuY3Rpb25zID0gbmV3IE1hcCgpOwogIC8vCiAgdmFyIG9yZGVyYm9va0NhY2hlID0ge307CiAgdmFyIG9wdGlvbiA9IHsKICAgIHVzZU9yaWdpbmFsRGF0YTogZmFsc2UsCiAgICBzaG93TG9nOiBmYWxzZQogIH07CiAgZnVuY3Rpb24gcG9zdE1lc3NhZ2UodG9waWMsIGRhdGEpIHsKICAgIHRvcGljU2VuZEluZm8udGhyb3R0bGVQb3N0TWVzc2FnZSh0b3BpYywgewogICAgICB0eXBlOiAnVVBEQVRFX0RBVEUnLAogICAgICB0b3BpYzogdG9waWMsCiAgICAgIGRhdGE6IGRhdGEKICAgIH0pOwogIH0KICBmdW5jdGlvbiBwcmludExvZ2dlcih0b3BpYywgbmFtZVNwYWNlLCByZXN1bHQpIHsKICAgIHZhciBpc09yaWdpbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogZmFsc2U7CiAgICBpZiAodG9waWMgPT09IE1hcmtldFR5cGVzLk1BUktFVF9DQU5ETEUgfHwgdG9waWMgPT09IE1hcmtldFR5cGVzLk1BUktfQ0FORExFKSB7CiAgICAgIF9sb2dnZXIoIlx1MzAxMCIuY29uY2F0KG5hbWVTcGFjZSwgIlx1MzAxMSIpLmNvbmNhdChpc09yaWdpbiA/ICdPcmlnaW4gRGF0YScgOiAnUGFyc2VkIERhdGEnLCAiIFJlY2VpdmVkIiksIHJlc3VsdCk7CiAgICB9IGVsc2UgewogICAgICBfbG9nZ2VyKCJcdTMwMTAiLmNvbmNhdCh0b3BpYykuY29uY2F0KG5hbWVTcGFjZSwgIlx1MzAxMSIpLmNvbmNhdChpc09yaWdpbiA/ICdPcmlnaW4gRGF0YScgOiAnUGFyc2VkIERhdGEnLCAiIFJlY2VpdmVkIiksIHJlc3VsdCk7CiAgICB9CiAgfQogIC8vIOaOpeaUtuS4u+e6v+eoi+a2iOaBrwogIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICB2YXIgX2V2ZW50JGRhdGEgPSBldmVudC5kYXRhLAogICAgICBhY3Rpb24gPSBfZXZlbnQkZGF0YS5hY3Rpb24sCiAgICAgIHBheWxvYWQgPSBfZXZlbnQkZGF0YS5wYXlsb2FkOwogICAgc3dpdGNoIChhY3Rpb24pIHsKICAgICAgY2FzZSAnSU5JVCc6CiAgICAgICAgb3B0aW9uID0gewogICAgICAgICAgdXNlT3JpZ2luYWxEYXRhOiBwYXlsb2FkLnVzZU9yaWdpbmFsRGF0YSwKICAgICAgICAgIHNob3dMb2c6IHBheWxvYWQuc2hvd0xvZwogICAgICAgIH07CiAgICAgICAgaW5pdFdzKHBheWxvYWQudXJsKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnU1VCU0NSSUJFJzoKICAgICAgICAvLyDorqLpmIUKICAgICAgICBzdWJzY3JpYmVUb3BpYyhfb2JqZWN0U3ByZWFkMiQyKHt9LCBwYXlsb2FkKSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ1VOU1VCU0NSSUJFJzoKICAgICAgICAvLyDlj5bmtojorqLpmIUKICAgICAgICB1bnN1YnNjcmliZVRvcGljKHBheWxvYWQucmVhbFRvcGljKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnU1VCU0NSSUJFX0RJUkVDVCc6CiAgICAgICAgc3Vic2NyaWJlVG9waWNEaXJlY3QoX29iamVjdFNwcmVhZDIkMih7fSwgcGF5bG9hZCkpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdVTlNVQlNDUklCRV9ESVJFQ1QnOgogICAgICAgIC8vIOWPlua2iOiuoumYhQogICAgICAgIHVuc3Vic2NyaWJlVG9waWNEaXJlY3QocGF5bG9hZC5yZWFsVG9waWMpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdDSEFOR0VfVVJMJzoKICAgICAgICBjaGFuZ2VVcmwocGF5bG9hZC51cmwpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdQQUdFX0FDVElWRV9DSEFOR0UnOgogICAgICAgIHNldFBhZ2VBY3RpdmUocGF5bG9hZC5pc0FjdGl2ZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ1VQREFURV9GVVRVUkVfT1BFTl9QUklDRV9MSVNUJzoKICAgICAgICAvLyBvcGVuUHJpY2VMaXN0CiAgICAgICAgb3BlblByaWNlTGlzdCA9IHBheWxvYWQub3BlblByaWNlTGlzdDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnU0FWRV9EQVRBJzoKICAgICAgICBpZiAocGF5bG9hZC5kYXRhTmFtZSA9PT0gJ3VwZGF0ZUVzdGltYXRlU2xpcHBhZ2VQYXJhbXMnKSB7CiAgICAgICAgICBwb3N0TWVzc2FnZSgnY2FsY0VzdGltYXRlU2xpcHBhZ2UnLCBoYW5kbGVDYWxjU2xpcHBhZ2UoX29iamVjdFNwcmVhZDIkMihfb2JqZWN0U3ByZWFkMiQyKHt9LCBwYXlsb2FkLmRhdGEgfHwge30pLCB7fSwgewogICAgICAgICAgICBvcmRlcmJvb2s6IG9yZGVyYm9va0NhY2hlCiAgICAgICAgICB9KSkpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBjb25zb2xlLndhcm4oJ1tXb3JrZXJdIOacquefpea2iOaBr+exu+WeizonLCBhY3Rpb24pOwogICAgfQogIH07CiAgLy8g5Yid5aeL5YyWIHdzCiAgZnVuY3Rpb24gaW5pdFdzKHVybCkgewogICAgaWYgKHdzSW5zdGFuY2UpIHJldHVybjsKICAgIHdzSW5zdGFuY2UgPSBuZXcgRWFzeVdTKCIiLmNvbmNhdCh1cmwsICI/dj0xIiksIHsKICAgICAgYXV0b0Nvbm5lY3Q6IHRydWUKICAgIH0pOwogICAgd3NJbnN0YW5jZS5vbihXZWJzb2NrZXRFdmVudHMuQ09OTkVDVCwgZnVuY3Rpb24gKCkgewogICAgICAvLyB3c+W3sui/nuaOpQogICAgICAvLyBXU0ZDVDogd2Vic29ja2V0IGZpcnN0IGNvbm5lY3QgdGltZQogICAgICB2YXIgV1NGQ1QgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHdzSW5zdGFuY2Uub3BlblN0YXJ0OwogICAgICBzZWxmLnBvc3RNZXNzYWdlKHsKICAgICAgICB0eXBlOiBXZWJzb2NrZXRFdmVudHMuQ09OTkVDVCwKICAgICAgICBkYXRhOiB7CiAgICAgICAgICBlOiAnQ29ubmVjdCcsCiAgICAgICAgICBXU0ZDVDogV1NGQ1QsCiAgICAgICAgICBzb2NrZXRJZDogd3NJbnN0YW5jZS5zb2NrZXRJZAogICAgICAgIH0KICAgICAgfSk7CiAgICB9KTsKICAgIHdzSW5zdGFuY2Uub24oV2Vic29ja2V0RXZlbnRzLlJFQ09OTkVDVCwgZnVuY3Rpb24gKCkgewogICAgICAvLyB3c+mHjei/ngogICAgICAvLyBXU0ZDVDogd2Vic29ja2V0IG8gdGltZQogICAgICB2YXIgV1NPVCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gd3NJbnN0YW5jZS5jb25uZWN0U3RhcnQ7CiAgICAgIHNlbGYucG9zdE1lc3NhZ2UoewogICAgICAgIHR5cGU6IFdlYnNvY2tldEV2ZW50cy5SRUNPTk5FQ1QsCiAgICAgICAgZGF0YTogewogICAgICAgICAgZTogJ1JlY29ubmVjdF9zdWNjZXNzJywKICAgICAgICAgIFdTT1Q6IFdTT1QsCiAgICAgICAgICBzb2NrZXRJZDogd3NJbnN0YW5jZS5zb2NrZXRJZAogICAgICAgIH0KICAgICAgfSk7CiAgICB9KTsKICAgIHdzSW5zdGFuY2Uub24oV2Vic29ja2V0RXZlbnRzLkNMT1NFLCBmdW5jdGlvbiAoX3JlZikgewogICAgICB2YXIgY29kZSA9IF9yZWYuY29kZSwKICAgICAgICByZWFzb24gPSBfcmVmLnJlYXNvbjsKICAgICAgLy8gd3Pmlq3lvIAKICAgICAgdmFyIHJlcG9ydCA9IHsKICAgICAgICBlOiAnQ2xvc2UnCiAgICAgIH07CiAgICAgIGlmIChjb2RlID09PSAxMDAwKSB7CiAgICAgICAgcmVwb3J0ID0gX29iamVjdFNwcmVhZDIkMihfb2JqZWN0U3ByZWFkMiQyKHt9LCByZXBvcnQpLCB7fSwgewogICAgICAgICAgY29kZTogY29kZSwKICAgICAgICAgIHJlYXNvbjogcmVhc29uLAogICAgICAgICAgc29ja2V0SWQ6IHdzSW5zdGFuY2Uuc29ja2V0SWQKICAgICAgICB9KTsKICAgICAgfQogICAgICBzZWxmLnBvc3RNZXNzYWdlKHsKICAgICAgICB0eXBlOiBXZWJzb2NrZXRFdmVudHMuQ0xPU0UsCiAgICAgICAgZGF0YTogcmVwb3J0CiAgICAgIH0pOwogICAgfSk7CiAgICB3c0luc3RhbmNlLm9uKFdlYnNvY2tldEV2ZW50cy5PUEVOX0VSUk9SLCBmdW5jdGlvbiAoX3JlZjIpIHsKICAgICAgdmFyIGNvZGUgPSBfcmVmMi5jb2RlLAogICAgICAgIHJlYXNvbiA9IF9yZWYyLnJlYXNvbjsKICAgICAgLy8g6L+e5o6l5aSx6LSlCiAgICAgIHNlbGYucG9zdE1lc3NhZ2UoewogICAgICAgIHR5cGU6IFdlYnNvY2tldEV2ZW50cy5PUEVOX0VSUk9SLAogICAgICAgIGRhdGE6IHsKICAgICAgICAgIGU6ICdvcGVuX2Vycm9yJywKICAgICAgICAgIGNvZGU6IGNvZGUsCiAgICAgICAgICByZWFzb246IHJlYXNvbiwKICAgICAgICAgIHNvY2tldElkOiB3c0luc3RhbmNlLnNvY2tldElkCiAgICAgICAgfQogICAgICB9KTsKICAgIH0pOwogICAgd3NJbnN0YW5jZS5vbihXZWJzb2NrZXRFdmVudHMuSEVBUlRfRVJST1IsIGZ1bmN0aW9uIChfcmVmMykgewogICAgICB2YXIgY29kZSA9IF9yZWYzLmNvZGUsCiAgICAgICAgcmVhc29uID0gX3JlZjMucmVhc29uOwogICAgICAvLyDlv4Pot7PlpLHotKUKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7CiAgICAgICAgdHlwZTogV2Vic29ja2V0RXZlbnRzLkhFQVJUX0VSUk9SLAogICAgICAgIGRhdGE6IHsKICAgICAgICAgIGU6ICdoZWFydF9lcnJvcicsCiAgICAgICAgICBjb2RlOiBjb2RlLAogICAgICAgICAgcmVhc29uOiByZWFzb24sCiAgICAgICAgICBzb2NrZXRJZDogd3NJbnN0YW5jZS5zb2NrZXRJZAogICAgICAgIH0KICAgICAgfSk7CiAgICB9KTsKICAgIHdzSW5zdGFuY2Uub24oV2Vic29ja2V0RXZlbnRzLkhFQVJUX0JBQ0ssIGZ1bmN0aW9uIChfcmVmNCkgewogICAgICB2YXIgY29kZSA9IF9yZWY0LmNvZGUsCiAgICAgICAgcmVhc29uID0gX3JlZjQucmVhc29uOwogICAgICAvLyDlv4Pot7Pov5Tlm54KICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7CiAgICAgICAgdHlwZTogV2Vic29ja2V0RXZlbnRzLkhFQVJUX0JBQ0ssCiAgICAgICAgZGF0YTogewogICAgICAgICAgZTogJ2hlYXJ0X2JhY2snLAogICAgICAgICAgY29kZTogY29kZSwKICAgICAgICAgIHJlYXNvbjogcmVhc29uLAogICAgICAgICAgc29ja2V0SWQ6IHdzSW5zdGFuY2Uuc29ja2V0SWQKICAgICAgICB9CiAgICAgIH0pOwogICAgfSk7CiAgICAvLyDph43ov57lpLHotKUKICAgIHdzSW5zdGFuY2Uub24oV2Vic29ja2V0RXZlbnRzLlJFQ09OTkVDVF9GQUlMRUQsIGZ1bmN0aW9uICgpIHsKICAgICAgLy8g5b+D6Lez6L+U5ZueCiAgICAgIHNlbGYucG9zdE1lc3NhZ2UoewogICAgICAgIHR5cGU6IFdlYnNvY2tldEV2ZW50cy5SRUNPTk5FQ1RfRkFJTEVELAogICAgICAgIGRhdGE6IHsKICAgICAgICAgIGU6ICdSZWNvbm5lY3RfZmFpbGVkJywKICAgICAgICAgIHNvY2tldElkOiB3c0luc3RhbmNlLnNvY2tldElkCiAgICAgICAgfQogICAgICB9KTsKICAgIH0pOwogICAgLy8g5byA5aeL6YeN6L+eCiAgICB3c0luc3RhbmNlLm9uKFdlYnNvY2tldEV2ZW50cy5SRUNPTk5FQ1RfU1RBUlQsIGZ1bmN0aW9uICgpIHsKICAgICAgLy8g5b+D6Lez6L+U5ZueCiAgICAgIHNlbGYucG9zdE1lc3NhZ2UoewogICAgICAgIHR5cGU6IFdlYnNvY2tldEV2ZW50cy5SRUNPTk5FQ1RfU1RBUlQsCiAgICAgICAgZGF0YTogewogICAgICAgICAgZTogJ1JlY29ubmVjdCcsCiAgICAgICAgICBzb2NrZXRJZDogd3NJbnN0YW5jZS5zb2NrZXRJZAogICAgICAgIH0KICAgICAgfSk7CiAgICB9KTsKICB9CiAgLy8g5Y+W5raI6K6i6ZiFIOe7mW1hcmsgbWFya2V055SoICjnm7TmjqXkvKAgdG9waWMpCiAgZnVuY3Rpb24gdW5zdWJzY3JpYmVUb3BpY0RpcmVjdChyZWFsVG9waWMpIHsKICAgIGlmICghd3NJbnN0YW5jZSkgcmV0dXJuOwogICAgd3NJbnN0YW5jZS5sZWF2ZShyZWFsVG9waWMpOwogIH0KICAvLyDliIfmjaIgd3MgdXJsCiAgZnVuY3Rpb24gY2hhbmdlVXJsKHVybCkgewogICAgaWYgKCF3c0luc3RhbmNlKSByZXR1cm47CiAgICB3c0luc3RhbmNlLmNoYW5nZVVybCh1cmwpOwogIH0KICAvLyDorr7nva7pobXpnaLmmL7npLov6ZqQ6JePCiAgZnVuY3Rpb24gc2V0UGFnZUFjdGl2ZShpc0FjdGl2ZSkgewogICAgaWYgKCF3c0luc3RhbmNlKSByZXR1cm47CiAgICB3c0luc3RhbmNlLnNldFBhZ2VBY3RpdmUoaXNBY3RpdmUpOwogIH0KICAvLyB0b3BpYyDnm7jlupTmlbDmja7ov4fmu6QKICBmdW5jdGlvbiBwYXJzZVdzRGF0YShfcmVmNSkgewogICAgdmFyIHRvcGljID0gX3JlZjUudG9waWMsCiAgICAgIG5hbWVTcGFjZSA9IF9yZWY1Lm5hbWVTcGFjZSwKICAgICAgcmVzdWx0ID0gX3JlZjUucmVzdWx0LAogICAgICBvYlBhcmFtcyA9IF9yZWY1Lm9iUGFyYW1zLAogICAgICBtdDVUaWNrZXJzQWxsUGFyYW1zID0gX3JlZjUubXQ1VGlja2Vyc0FsbFBhcmFtcywKICAgICAgcHVibGljUGFyYW1zID0gX3JlZjUucHVibGljUGFyYW1zLAogICAgICByZWFsVG9waWMgPSBfcmVmNS5yZWFsVG9waWM7CiAgICBpZiAob3B0aW9uLnNob3dMb2cgJiYgb3B0aW9uLnNob3dMb2cgPT09ICdvcmlnaW4nKSB7CiAgICAgIC8vIE5PVElDRTog5bqP5YiX5YyWcmVzdWx05piv5Li65LqG6Ziy5q2iY29uc29sZS5sb2fmiZPljbDlvILmraXmmL7npLrpl67popgKICAgICAgcHJpbnRMb2dnZXIodG9waWMsIG5hbWVTcGFjZSwgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyZXN1bHQpKSwgdHJ1ZSk7CiAgICB9CiAgICBzd2l0Y2ggKHRvcGljKSB7CiAgICAgIC8vIGluc3RydW1lbnQKICAgICAgY2FzZSBQdWJsaWNXc1RvcGljcy5JbnN0cnVtZW50SW5mb19IOgogICAgICBjYXNlIFB1YmxpY1dzVG9waWNzLkluc3RydW1lbnRJbmZvX006CiAgICAgICAgewogICAgICAgICAgdmFyIGluc3RydW1lbnQgPSByZXN1bHQ7CiAgICAgICAgICBpZiAoIW9wdGlvbi51c2VPcmlnaW5hbERhdGEpIHsKICAgICAgICAgICAgaW5zdHJ1bWVudCA9IGhhbmRsZVNpbmdsZVN5bWJvbCQxKG5hbWVTcGFjZSwgcmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIC8vIOaXpeW/lwogICAgICAgICAgaWYgKG9wdGlvbi5zaG93TG9nICYmIG9wdGlvbi5zaG93TG9nID09PSAncGFyc2VkJykgewogICAgICAgICAgICBwcmludExvZ2dlcih0b3BpYywgbmFtZVNwYWNlLCBpbnN0cnVtZW50KTsKICAgICAgICAgIH0KICAgICAgICAgIHBvc3RNZXNzYWdlKHRvcGljLCBpbnN0cnVtZW50KTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgLy8gLy8gb3JkZXJCb29rCiAgICAgIGNhc2UgUHVibGljV3NUb3BpY3MuT3JkZXJCb29rOgogICAgICAgIHsKICAgICAgICAgIHZhciBvcmRlckJvb2sgPSBvcmRlckJvb2tIYW5kbGVyJDEobmFtZVNwYWNlLCByZXN1bHQpOwogICAgICAgICAgaWYgKG9wdGlvbi5zaG93TG9nICYmIG9wdGlvbi5zaG93TG9nID09PSAncGFyc2VkJykgewogICAgICAgICAgICB2YXIgbGV2ZWwgPSBvYlBhcmFtcy5sZXZlbCwKICAgICAgICAgICAgICByYXRpbyA9IG9iUGFyYW1zLnJhdGlvOwogICAgICAgICAgICBwcmludExvZ2dlcigiIi5jb25jYXQodG9waWMpLmNvbmNhdChsZXZlbCwgIkBtIikuY29uY2F0KHJhdGlvLCAiLkguIiksIG5hbWVTcGFjZSwgb3JkZXJCb29rKTsKICAgICAgICAgIH0KICAgICAgICAgIG9yZGVyYm9va0NhY2hlID0gb3JkZXJCb29rOwogICAgICAgICAgcG9zdE1lc3NhZ2UodG9waWMsIG9yZGVyQm9vayk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIGNhc2UgUHVibGljT3B0aW9uRXZlbnRzLk9yZGVyQm9vazoKICAgICAgICB7CiAgICAgICAgICB2YXIgX29yZGVyQm9vayA9IG9yZGVyQm9va09wdGlvbkhhbmRsZXIobmFtZVNwYWNlLCByZXN1bHQpOwogICAgICAgICAgaWYgKG9wdGlvbi5zaG93TG9nICYmIG9wdGlvbi5zaG93TG9nID09PSAncGFyc2VkJykgewogICAgICAgICAgICB2YXIgX2xldmVsID0gb2JQYXJhbXMubGV2ZWw7CiAgICAgICAgICAgIHByaW50TG9nZ2VyKCIiLmNvbmNhdCh0b3BpYykuY29uY2F0KF9sZXZlbCwgIi4iKSwgbmFtZVNwYWNlLCBfb3JkZXJCb29rKTsKICAgICAgICAgIH0KICAgICAgICAgIHBvc3RNZXNzYWdlKHRvcGljLCBfb3JkZXJCb29rKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgY2FzZSBQdWJsaWNXc1RvcGljcy5NVDVPcmRlckJvb2s6CiAgICAgICAgewogICAgICAgICAgdmFyIF9vcmRlckJvb2syID0gb3JkZXJCb29rTXQ1SGFuZGxlcihuYW1lU3BhY2UsIHJlc3VsdCk7CiAgICAgICAgICBpZiAob3B0aW9uLnNob3dMb2cgJiYgb3B0aW9uLnNob3dMb2cgPT09ICdwYXJzZWQnKSB7CiAgICAgICAgICAgIHByaW50TG9nZ2VyKCIiLmNvbmNhdCh0b3BpYywgIjUuIiksIG5hbWVTcGFjZSwgX29yZGVyQm9vazIpOwogICAgICAgICAgfQogICAgICAgICAgcG9zdE1lc3NhZ2UodG9waWMsIF9vcmRlckJvb2syKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgLy8gLy8gcmVjZW50VHJhZGUKICAgICAgY2FzZSBQdWJsaWNXc1RvcGljcy5SZWNlbnRUcmFkZToKICAgICAgICB7CiAgICAgICAgICB2YXIgcmVjZW50VHJhZGUgPSByZWNlbnRUcmFkZUhhbmRsZXIkMShuYW1lU3BhY2UsIHJlc3VsdCk7CiAgICAgICAgICBpZiAob3B0aW9uLnNob3dMb2cgJiYgb3B0aW9uLnNob3dMb2cgPT09ICdwYXJzZWQnKSB7CiAgICAgICAgICAgIHByaW50TG9nZ2VyKHRvcGljLCBuYW1lU3BhY2UsIHJlY2VudFRyYWRlKTsKICAgICAgICAgIH0KICAgICAgICAgIHBvc3RNZXNzYWdlKHRvcGljLCByZWNlbnRUcmFkZSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIC8vIC8vIGluc3RydW1lbnRfaW5mby5hbGwKICAgICAgY2FzZSBQdWJsaWNXc1RvcGljcy5JbnN0cnVtZW50SW5mb0FsbDoKICAgICAgICB7CiAgICAgICAgICB2YXIgYWxsU3ltYm9scyA9IHJlc3VsdDsKICAgICAgICAgIGlmICghb3B0aW9uLnVzZU9yaWdpbmFsRGF0YSkgewogICAgICAgICAgICB2YXIgX2FsbFN5bWJvbHM7CiAgICAgICAgICAgIGFsbFN5bWJvbHMgPSBoYW5kbGVBbGxTeW1ib2wkMShyZXN1bHQpOwogICAgICAgICAgICAvLyBUT0RPIG9wZW5QcmljZU1hcDogW2tleTpzdHJpbmddOiBudW1iZXIKICAgICAgICAgICAgYWxsU3ltYm9scyA9IGhhbmRsZUFsbFN5bWJvbFF1b3RlKCgoX2FsbFN5bWJvbHMgPSBhbGxTeW1ib2xzKSA9PT0gbnVsbCB8fCBfYWxsU3ltYm9scyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2FsbFN5bWJvbHMuZGF0YSkgfHwgW10sIG9wZW5QcmljZUxpc3QpOwogICAgICAgICAgfQogICAgICAgICAgLy8g5pel5b+XCiAgICAgICAgICBpZiAob3B0aW9uLnNob3dMb2cgJiYgb3B0aW9uLnNob3dMb2cgPT09ICdwYXJzZWQnKSB7CiAgICAgICAgICAgIHByaW50TG9nZ2VyKHRvcGljLCBuYW1lU3BhY2UsIGFsbFN5bWJvbHMpOwogICAgICAgICAgfQogICAgICAgICAgcG9zdE1lc3NhZ2UodG9waWMsIGFsbFN5bWJvbHMpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAvLyAvLyBwdWJsaWMuc3ltYm9sLm5vdGlmeQogICAgICBjYXNlIFB1YmxpY1dzVG9waWNzLlRpbWVDb2luU3ltYm9sTm90aWZ5OgogICAgICAgIHsKICAgICAgICAgIHBvc3RNZXNzYWdlKHRvcGljLCByZXN1bHQpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAvLyAvLyBwdWJsaWMubm90aWNlCiAgICAgIGNhc2UgUHVibGljV3NUb3BpY3MuUHVibGljTm90aWNlOgogICAgICAgIHsKICAgICAgICAgIHBvc3RNZXNzYWdlKHRvcGljLCByZXN1bHQpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAvLyAvLyDluILku7cgbWFya2V0CiAgICAgIGNhc2UgTWFya2V0VHlwZXMuTUFSS0VUX0NBTkRMRToKICAgICAgICB7CiAgICAgICAgICBwb3N0TWVzc2FnZSh0b3BpYywgaGFuZGxlQ2FuZGxlTXNnKG5hbWVTcGFjZSwgcmVzdWx0KSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIC8vIOagh+iusOS7tyBtYXJrCiAgICAgIGNhc2UgTWFya2V0VHlwZXMuTUFSS19DQU5ETEU6CiAgICAgICAgewogICAgICAgICAgcG9zdE1lc3NhZ2UodG9waWMsIGhhbmRsZU1hcmtQcmljZU1zZyhuYW1lU3BhY2UsIHJlc3VsdCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAvLyBmcyBvYgogICAgICBjYXNlIFB1YmxpY0ZzVG9waWNzLk9yZGVyQm9vazoKICAgICAgICB7CiAgICAgICAgICB2YXIgX29yZGVyQm9vazMgPSBvcmRlckJvb2tIYW5kbGVyKG5hbWVTcGFjZSwgcmVzdWx0KTsKICAgICAgICAgIGlmIChvcHRpb24uc2hvd0xvZyAmJiBvcHRpb24uc2hvd0xvZyA9PT0gJ3BhcnNlZCcpIHsKICAgICAgICAgICAgdmFyIF9sZXZlbDIgPSBvYlBhcmFtcy5sZXZlbDsKICAgICAgICAgICAgcHJpbnRMb2dnZXIoIiIuY29uY2F0KHRvcGljKS5jb25jYXQoX2xldmVsMiwgIi4iKSwgbmFtZVNwYWNlLCBfb3JkZXJCb29rMyk7CiAgICAgICAgICB9CiAgICAgICAgICBwb3N0TWVzc2FnZSh0b3BpYywgX29yZGVyQm9vazMpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICBjYXNlIFB1YmxpY0ZzVG9waWNzLkluc3RydW1lbnRJbmZvOgogICAgICAgIHsKICAgICAgICAgIHZhciBfaW5zdHJ1bWVudCA9IHJlc3VsdDsKICAgICAgICAgIGlmICghb3B0aW9uLnVzZU9yaWdpbmFsRGF0YSkgewogICAgICAgICAgICBfaW5zdHJ1bWVudCA9IGhhbmRsZVNpbmdsZVN5bWJvbChuYW1lU3BhY2UsIHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICAvLyDml6Xlv5cKICAgICAgICAgIGlmIChvcHRpb24uc2hvd0xvZyAmJiBvcHRpb24uc2hvd0xvZyA9PT0gJ3BhcnNlZCcpIHsKICAgICAgICAgICAgcHJpbnRMb2dnZXIodG9waWMsIG5hbWVTcGFjZSwgX2luc3RydW1lbnQpOwogICAgICAgICAgfQogICAgICAgICAgcG9zdE1lc3NhZ2UodG9waWMsIF9pbnN0cnVtZW50KTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgY2FzZSBQdWJsaWNGc1RvcGljcy5JbnN0cnVtZW50SW5mb0FsbDoKICAgICAgICB7CiAgICAgICAgICB2YXIgX2FsbFN5bWJvbHMyID0gcmVzdWx0OwogICAgICAgICAgaWYgKCFvcHRpb24udXNlT3JpZ2luYWxEYXRhKSB7CiAgICAgICAgICAgIF9hbGxTeW1ib2xzMiA9IGhhbmRsZUFsbFN5bWJvbChyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgLy8g5pel5b+XCiAgICAgICAgICBpZiAob3B0aW9uLnNob3dMb2cgJiYgb3B0aW9uLnNob3dMb2cgPT09ICdwYXJzZWQnKSB7CiAgICAgICAgICAgIHByaW50TG9nZ2VyKHRvcGljLCBuYW1lU3BhY2UsIF9hbGxTeW1ib2xzMik7CiAgICAgICAgICB9CiAgICAgICAgICBwb3N0TWVzc2FnZSh0b3BpYywgX2FsbFN5bWJvbHMyKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgLy8gcmVjZW50VHJhZGUKICAgICAgY2FzZSBQdWJsaWNGc1RvcGljcy5SZWNlbnRUcmFkZToKICAgICAgICB7CiAgICAgICAgICB2YXIgX3JlY2VudFRyYWRlID0gcmVjZW50VHJhZGVIYW5kbGVyKG5hbWVTcGFjZSwgcmVzdWx0KTsKICAgICAgICAgIGlmIChvcHRpb24uc2hvd0xvZyAmJiBvcHRpb24uc2hvd0xvZyA9PT0gJ3BhcnNlZCcpIHsKICAgICAgICAgICAgcHJpbnRMb2dnZXIodG9waWMsIG5hbWVTcGFjZSwgX3JlY2VudFRyYWRlKTsKICAgICAgICAgIH0KICAgICAgICAgIHBvc3RNZXNzYWdlKHRvcGljLCBfcmVjZW50VHJhZGUpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAvLyBtdDUudGlja2Vycy5hbGwKICAgICAgY2FzZSBQdWJsaWNXc1RvcGljcy5NVDVUaWNrZXJzQWxsOgogICAgICAgIHsKICAgICAgICAgIHZhciBfcmVzdWx0JGRhdGE7CiAgICAgICAgICB2YXIgZGF0YSA9IG10NVRpY2tlcnNBbGxGbigoX3Jlc3VsdCRkYXRhID0gcmVzdWx0ID09PSBudWxsIHx8IHJlc3VsdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogcmVzdWx0LmRhdGEpICE9PSBudWxsICYmIF9yZXN1bHQkZGF0YSAhPT0gdm9pZCAwID8gX3Jlc3VsdCRkYXRhIDogW10sIG10NVRpY2tlcnNBbGxQYXJhbXMsIG10NVRpY2tlcnNBbGxNYXApOwogICAgICAgICAgbXQ1VGlja2Vyc0FsbE1hcCA9IF9vYmplY3RTcHJlYWQyJDIoX29iamVjdFNwcmVhZDIkMih7fSwgbXQ1VGlja2Vyc0FsbE1hcCksIGRhdGEpOwogICAgICAgICAgLy8g6YeN5paw6K6h566XbXQ1VGlja2Vyc0FsbE1hcOmHjOeahHNlc3Npb25UcmFkZUNoZWNrCiAgICAgICAgICB2YXIgX3JlZjYgPSBtdDVUaWNrZXJzQWxsUGFyYW1zIHx8IHsKICAgICAgICAgICAgICBhbGxTeW1ib2xDb25maWc6IHt9LAogICAgICAgICAgICAgIGxhc3RSZXFTZXJ2ZXJUaW1lOiAwLAogICAgICAgICAgICAgIHNlcnZlclRpbWU6IDAKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX3JlZjYkYWxsU3ltYm9sQ29uZmlnID0gX3JlZjYuYWxsU3ltYm9sQ29uZmlnLAogICAgICAgICAgICBhbGxTeW1ib2xDb25maWcgPSBfcmVmNiRhbGxTeW1ib2xDb25maWcgPT09IHZvaWQgMCA/IHt9IDogX3JlZjYkYWxsU3ltYm9sQ29uZmlnLAogICAgICAgICAgICBsYXN0UmVxU2VydmVyVGltZSA9IF9yZWY2Lmxhc3RSZXFTZXJ2ZXJUaW1lLAogICAgICAgICAgICBzZXJ2ZXJUaW1lID0gX3JlZjYuc2VydmVyVGltZTsKICAgICAgICAgIGlmIChsYXN0UmVxU2VydmVyVGltZSAmJiBzZXJ2ZXJUaW1lICYmIE9iamVjdC5rZXlzKGFsbFN5bWJvbENvbmZpZykubGVuZ3RoID4gMCkgewogICAgICAgICAgICBPYmplY3QudmFsdWVzKG10NVRpY2tlcnNBbGxNYXApLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICAgICAgICB2YXIgX2FsbFN5bWJvbENvbmZpZyRpdGVtOwogICAgICAgICAgICAgIHZhciBzZXNzaW9ucyA9IChhbGxTeW1ib2xDb25maWcgPT09IG51bGwgfHwgYWxsU3ltYm9sQ29uZmlnID09PSB2b2lkIDAgfHwgKF9hbGxTeW1ib2xDb25maWckaXRlbSA9IGFsbFN5bWJvbENvbmZpZ1tpdGVtLnN5bWJvbF0pID09PSBudWxsIHx8IF9hbGxTeW1ib2xDb25maWckaXRlbSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2FsbFN5bWJvbENvbmZpZyRpdGVtLnNlc3Npb25zKSB8fCBbXTsKICAgICAgICAgICAgICBpdGVtLnNlc3Npb25UcmFkZUNoZWNrID0gZ2V0U3ltYm9sU2Vzc2lvblRyYWRlQ2hlY2soc2VydmVyVGltZSwgbGFzdFJlcVNlcnZlclRpbWUsIHNlc3Npb25zKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgICB2YXIgdGhyb3R0bGVUaW1lID0gdG9waWNUaHJvdHRsZUNvbmZpZy5nZXQodG9waWMpOwogICAgICAgICAgaWYgKHRocm90dGxlVGltZSAmJiB0aHJvdHRsZVRpbWUgPiAwKSB7CiAgICAgICAgICAgIGlmICghdGhyb3R0bGVGdW5jdGlvbnMuaGFzKHRvcGljKSkgewogICAgICAgICAgICAgIHZhciBfdGhyb3R0bGVkRm4gPSBsb2Rhc2hfdGhyb3R0bGUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UodG9waWMsIG10NVRpY2tlcnNBbGxNYXApOwogICAgICAgICAgICAgIH0sIHRocm90dGxlVGltZSk7CiAgICAgICAgICAgICAgdGhyb3R0bGVGdW5jdGlvbnMuc2V0KHRvcGljLCBfdGhyb3R0bGVkRm4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB0aHJvdHRsZWRGbiA9IHRocm90dGxlRnVuY3Rpb25zLmdldCh0b3BpYyk7CiAgICAgICAgICAgIHRocm90dGxlZEZuKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwb3N0TWVzc2FnZSh0b3BpYywgbXQ1VGlja2Vyc0FsbE1hcCk7CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIC8vIG10NS5rbGluZS5bbWludXRlc10uW3N5bWJvbF0KICAgICAgY2FzZSBQdWJsaWNXc1RvcGljcy5NVDVLbGluZToKICAgICAgICB7CiAgICAgICAgICB2YXIgX3Jlc3VsdCRkYXRhMjsKICAgICAgICAgIHZhciBfZGF0YSA9IGZvcm1hdE10NUtsaW5lRm4oKF9yZXN1bHQkZGF0YTIgPSByZXN1bHQgPT09IG51bGwgfHwgcmVzdWx0ID09PSB2b2lkIDAgPyB2b2lkIDAgOiByZXN1bHQuZGF0YSkgIT09IG51bGwgJiYgX3Jlc3VsdCRkYXRhMiAhPT0gdm9pZCAwID8gX3Jlc3VsdCRkYXRhMiA6IFtdLCByZWFsVG9waWMsIHB1YmxpY1BhcmFtcyk7CiAgICAgICAgICBwb3N0TWVzc2FnZSh0b3BpYywgewogICAgICAgICAgICB0b3BpYzogcmVhbFRvcGljLAogICAgICAgICAgICBkYXRhOiBfZGF0YSB8fCBbXQogICAgICAgICAgfSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIC8vIGFscGhhLnRpY2tlci5hbGwKICAgICAgY2FzZSBQdWJsaWNXc1RvcGljcy5BbHBoYVRpY2tlcnNBbGw6CiAgICAgICAgewogICAgICAgICAgdmFyIF9hbGxTeW1ib2xzMyA9IHJlc3VsdDsKICAgICAgICAgIGlmICghb3B0aW9uLnVzZU9yaWdpbmFsRGF0YSkgewogICAgICAgICAgICBfYWxsU3ltYm9sczMgPSBoYW5kbGVBbHBoYUFsbFN5bWJvbChyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgLy8g5pel5b+XCiAgICAgICAgICBpZiAob3B0aW9uLnNob3dMb2cgJiYgb3B0aW9uLnNob3dMb2cgPT09ICdwYXJzZWQnKSB7CiAgICAgICAgICAgIHByaW50TG9nZ2VyKHRvcGljLCBuYW1lU3BhY2UsIF9hbGxTeW1ib2xzMyk7CiAgICAgICAgICB9CiAgICAgICAgICBwb3N0TWVzc2FnZSh0b3BpYywgX2FsbFN5bWJvbHMzKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgZGVmYXVsdDoKICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZQogICAgICAgIGNvbnNvbGUud2FybignQnlGYnVQdWJsaWNXczogdG9waWMgdHlwZSBub3Qgc3VwcG9ydCA9PicsIHRvcGljKTsKICAgIH0KICB9CiAgLy8g6K6i6ZiFIHRvcGljCiAgZnVuY3Rpb24gc3Vic2NyaWJlVG9waWMocGFyYW1zKSB7CiAgICBpZiAoIXdzSW5zdGFuY2UpIHJldHVybjsKICAgIHZhciB0b3BpYyA9IHBhcmFtcy50b3BpYywKICAgICAgcmVhbFRvcGljID0gcGFyYW1zLnJlYWxUb3BpYywKICAgICAgbXQ1VGlja2Vyc0FsbFBhcmFtcyA9IHBhcmFtcy5tdDVUaWNrZXJzQWxsUGFyYW1zLAogICAgICBwdWJsaWNQYXJhbXMgPSBwYXJhbXMucHVibGljUGFyYW1zLAogICAgICBuYW1lU3BhY2UgPSBwYXJhbXMubmFtZVNwYWNlLAogICAgICBvYlBhcmFtcyA9IHBhcmFtcy5vYlBhcmFtcywKICAgICAgdGhyb3R0bGVUaW1lID0gcGFyYW1zLnRocm90dGxlVGltZTsKICAgIC8vIOS/neWtmOivpXRvcGlj55qE6IqC5rWB6YWN572uCiAgICBpZiAodGhyb3R0bGVUaW1lICYmIHRocm90dGxlVGltZSA+PSAwKSB7CiAgICAgIHRvcGljVGhyb3R0bGVDb25maWcuc2V0KHRvcGljLCB0aHJvdHRsZVRpbWUpOwogICAgfQogICAgd3NJbnN0YW5jZS5jaGFubmVsKHJlYWxUb3BpYywgZnVuY3Rpb24gKHJlc3VsdCkgewogICAgICBwYXJzZVdzRGF0YSh7CiAgICAgICAgdG9waWM6IHRvcGljLAogICAgICAgIG5hbWVTcGFjZTogbmFtZVNwYWNlLAogICAgICAgIHJlc3VsdDogcmVzdWx0LAogICAgICAgIG9iUGFyYW1zOiBvYlBhcmFtcywKICAgICAgICBtdDVUaWNrZXJzQWxsUGFyYW1zOiBtdDVUaWNrZXJzQWxsUGFyYW1zLAogICAgICAgIHJlYWxUb3BpYzogcmVhbFRvcGljLAogICAgICAgIHB1YmxpY1BhcmFtczogcHVibGljUGFyYW1zCiAgICAgIH0pOwogICAgfSk7CiAgfQogIC8vIOWPlua2iOiuoumYhQogIGZ1bmN0aW9uIHVuc3Vic2NyaWJlVG9waWMocmVhbFRvcGljKSB7CiAgICBpZiAoIXdzSW5zdGFuY2UpIHJldHVybjsKICAgIHdzSW5zdGFuY2UubGVhdmUocmVhbFRvcGljKTsKICB9CiAgLy8g6K6i6ZiFIOe7mW1hcmsgbWFya2V055SoICjnm7TmjqXkvKAgdG9waWMpCiAgZnVuY3Rpb24gc3Vic2NyaWJlVG9waWNEaXJlY3QocGFyYW1zKSB7CiAgICBpZiAoIXdzSW5zdGFuY2UpIHJldHVybjsKICAgIHZhciB0b3BpYyA9IHBhcmFtcy50b3BpYywKICAgICAgcmVhbFRvcGljID0gcGFyYW1zLnJlYWxUb3BpYywKICAgICAgbmFtZVNwYWNlID0gcGFyYW1zLm5hbWVTcGFjZTsKICAgIHdzSW5zdGFuY2UuY2hhbm5lbChyZWFsVG9waWMsIGZ1bmN0aW9uIChyZXN1bHQpIHsKICAgICAgcGFyc2VXc0RhdGEoewogICAgICAgIHRvcGljOiB0b3BpYywKICAgICAgICBuYW1lU3BhY2U6IG5hbWVTcGFjZSwKICAgICAgICByZXN1bHQ6IHJlc3VsdCwKICAgICAgICByZWFsVG9waWM6IHJlYWxUb3BpYwogICAgICB9KTsKICAgIH0pOwogIH0KCn0pKCk7Cgo=",function(g){var I,C,A;return new Worker(k=k||(C=(I=function(g,I){var C=atob(g);if(I){for(var A=new Uint8Array(C.length),Z=0,G=C.length;Z0){for(G+=l,I=1;IC)throw Error(r+g)}function gc(g,I,C,A){var Z,G,l,b;for(G=g[0];G>=10;G/=10)--I;return--I<0?(I+=7,Z=0):(Z=Math.ceil((I+1)/7),I%=7),G=gg(10,7-I),b=g[Z]%G|0,null==A?I<3?(0==I?b=b/100|0:1==I&&(b=b/10|0),l=C<4&&99999==b||C>3&&49999==b||5e4==b||0==b):l=(C<4&&b+1==G||C>3&&b+1==G/2)&&(g[Z+1]/G/100|0)==gg(10,I-2)-1||(b==G/2||0==b)&&(g[Z+1]/G/100|0)==0:I<4?(0==I?b=b/1e3|0:1==I?b=b/100|0:2==I&&(b=b/10|0),l=(A||C<4)&&9999==b||!A&&C>3&&4999==b):l=((A||C<4)&&b+1==G||!A&&C>3&&b+1==G/2)&&(g[Z+1]/G/1e3|0)==gg(10,I-3)-1,l}function gi(g,I,C){for(var A,Z,G=[0],l=0,b=g.length;lC-1&&(void 0===G[A+1]&&(G[A+1]=0),G[A+1]+=G[A]/C|0,G[A]%=C)}return G.reverse()}gb.absoluteValue=gb.abs=function(){var g=new this.constructor(this);return g.s<0&&(g.s=1),gW(g)},gb.ceil=function(){return gW(new this.constructor(this),this.e+1,2)},gb.clampedTo=gb.clamp=function(g,I){var C=this.constructor;if(g=new C(g),I=new C(I),!g.s||!I.s)return new C(NaN);if(g.gt(I))throw Error(r+I);return 0>this.cmp(g)?g:this.cmp(I)>0?I:new C(this)},gb.comparedTo=gb.cmp=function(g){var I,C,A,Z,G=this.d,l=(g=new this.constructor(g)).d,b=this.s,B=g.s;if(!G||!l)return b&&B?b!==B?b:G===l?0:!G^b<0?1:-1:NaN;if(!G[0]||!l[0])return G[0]?b:l[0]?-B:0;if(b!==B)return b;if(this.e!==g.e)return this.e>g.e^b<0?1:-1;for(I=0,C=(A=G.length)<(Z=l.length)?A:Z;Il[I]^b<0?1:-1;return A===Z?0:A>Z^b<0?1:-1},gb.cosine=gb.cos=function(){var g,I,C=this,A=C.constructor;return C.d?C.d[0]?(g=A.precision,I=A.rounding,A.precision=g+Math.max(C.e,C.sd())+7,A.rounding=1,C=function(g,I){var C,A,Z;if(I.isZero())return I;(A=I.d.length)<32?Z=(1/gp(4,C=Math.ceil(A/3))).toString():(C=16,Z="2.3283064365386962890625e-10"),g.precision+=C,I=gu(g,1,I.times(Z),new g(1));for(var G=C;G--;){var l=I.times(I);I=l.times(l).minus(l).times(8).plus(1)}return g.precision-=C,I}(A,gF(A,C)),A.precision=g,A.rounding=I,gW(2==z||3==z?C.neg():C,g,I,!0)):new A(1):new A(NaN)},gb.cubeRoot=gb.cbrt=function(){var g,I,C,A,Z,G,l,b,B,d,c=this.constructor;if(!this.isFinite()||this.isZero())return new c(this);for(E=!1,(G=this.s*gg(this.s*this,1/3))&&Math.abs(G)!=1/0?A=new c(G.toString()):(C=gB(this.d),(G=((g=this.e)-C.length+1)%3)&&(C+=1==G||-2==G?"0":"00"),G=gg(C,1/3),g=$((g+1)/3)-(g%3==(g<0?-1:2)),(A=new c(C=G==1/0?"5e"+g:(C=G.toExponential()).slice(0,C.indexOf("e")+1)+g)).s=this.s),l=(g=c.precision)+3;;)if(A=gm((d=(B=(b=A).times(b).times(b)).plus(this)).plus(this).times(b),d.plus(B),l+2,1),gB(b.d).slice(0,l)===(C=gB(A.d)).slice(0,l)){if("9999"!=(C=C.slice(l-3,l+1))&&(Z||"4999"!=C)){+C&&(+C.slice(1)||"5"!=C.charAt(0))||(gW(A,g+1,1),I=!A.times(A).times(A).eq(this));break}if(!Z&&(gW(b,g+1,0),b.times(b).times(b).eq(this))){A=b;break}l+=4,Z=1}return E=!0,gW(A,g,c.rounding,I)},gb.decimalPlaces=gb.dp=function(){var g,I=this.d,C=NaN;if(I){if(C=((g=I.length-1)-$(this.e/7))*7,g=I[g])for(;g%10==0;g/=10)C--;C<0&&(C=0)}return C},gb.dividedBy=gb.div=function(g){return gm(this,new this.constructor(g))},gb.dividedToIntegerBy=gb.divToInt=function(g){var I=this.constructor;return gW(gm(this,new I(g),0,1,1),I.precision,I.rounding)},gb.equals=gb.eq=function(g){return 0===this.cmp(g)},gb.floor=function(){return gW(new this.constructor(this),this.e+1,3)},gb.greaterThan=gb.gt=function(g){return this.cmp(g)>0},gb.greaterThanOrEqualTo=gb.gte=function(g){var I=this.cmp(g);return 1==I||0===I},gb.hyperbolicCosine=gb.cosh=function(){var g,I,C,A,Z,G=this,l=G.constructor,b=new l(1);if(!G.isFinite())return new l(G.s?1/0:NaN);if(G.isZero())return b;C=l.precision,A=l.rounding,l.precision=C+Math.max(G.e,G.sd())+4,l.rounding=1,(Z=G.d.length)<32?I=(1/gp(4,g=Math.ceil(Z/3))).toString():(g=16,I="2.3283064365386962890625e-10"),G=gu(l,1,G.times(I),new l(1),!0);for(var B,d=g,c=new l(8);d--;)B=G.times(G),G=b.minus(B.times(c.minus(B.times(c))));return gW(G,l.precision=C,l.rounding=A,!0)},gb.hyperbolicSine=gb.sinh=function(){var g,I,C,A,Z=this,G=Z.constructor;if(!Z.isFinite()||Z.isZero())return new G(Z);if(I=G.precision,C=G.rounding,G.precision=I+Math.max(Z.e,Z.sd())+4,G.rounding=1,(A=Z.d.length)<3)Z=gu(G,2,Z,Z,!0);else{g=(g=1.4*Math.sqrt(A))>16?16:0|g,Z=gu(G,2,Z=Z.times(1/gp(5,g)),Z,!0);for(var l,b=new G(5),B=new G(16),d=new G(20);g--;)l=Z.times(Z),Z=Z.times(b.plus(l.times(B.times(l).plus(d))))}return G.precision=I,G.rounding=C,gW(Z,I,C,!0)},gb.hyperbolicTangent=gb.tanh=function(){var g,I,C=this.constructor;return this.isFinite()?this.isZero()?new C(this):(g=C.precision,I=C.rounding,C.precision=g+7,C.rounding=1,gm(this.sinh(),this.cosh(),C.precision=g,C.rounding=I)):new C(this.s)},gb.inverseCosine=gb.acos=function(){var g=this,I=g.constructor,C=g.abs().cmp(1),A=I.precision,Z=I.rounding;return -1!==C?0===C?g.isNeg()?gY(I,A,Z):new I(0):new I(NaN):g.isZero()?gY(I,A+4,Z).times(.5):(I.precision=A+6,I.rounding=1,g=new I(1).minus(g).div(g.plus(1)).sqrt().atan(),I.precision=A,I.rounding=Z,g.times(2))},gb.inverseHyperbolicCosine=gb.acosh=function(){var g,I,C=this,A=C.constructor;return C.lte(1)?new A(C.eq(1)?0:NaN):C.isFinite()?(g=A.precision,I=A.rounding,A.precision=g+Math.max(Math.abs(C.e),C.sd())+4,A.rounding=1,E=!1,C=C.times(C).minus(1).sqrt().plus(C),E=!0,A.precision=g,A.rounding=I,C.ln()):new A(C)},gb.inverseHyperbolicSine=gb.asinh=function(){var g,I,C=this,A=C.constructor;return!C.isFinite()||C.isZero()?new A(C):(g=A.precision,I=A.rounding,A.precision=g+2*Math.max(Math.abs(C.e),C.sd())+6,A.rounding=1,E=!1,C=C.times(C).plus(1).sqrt().plus(C),E=!0,A.precision=g,A.rounding=I,C.ln())},gb.inverseHyperbolicTangent=gb.atanh=function(){var g,I,C,A,Z=this,G=Z.constructor;return Z.isFinite()?Z.e>=0?new G(Z.abs().eq(1)?Z.s/0:Z.isZero()?Z:NaN):(g=G.precision,I=G.rounding,Math.max(A=Z.sd(),g)<-(2*Z.e)-1)?gW(new G(Z),g,I,!0):(G.precision=C=A-Z.e,Z=gm(Z.plus(1),new G(1).minus(Z),C+g,1),G.precision=g+4,G.rounding=1,Z=Z.ln(),G.precision=g,G.rounding=I,Z.times(.5)):new G(NaN)},gb.inverseSine=gb.asin=function(){var g,I,C,A,Z=this,G=Z.constructor;return Z.isZero()?new G(Z):(I=Z.abs().cmp(1),C=G.precision,A=G.rounding,-1!==I)?0===I?((g=gY(G,C+4,A).times(.5)).s=Z.s,g):new G(NaN):(G.precision=C+6,G.rounding=1,Z=Z.div(new G(1).minus(Z.times(Z)).sqrt().plus(1)).atan(),G.precision=C,G.rounding=A,Z.times(2))},gb.inverseTangent=gb.atan=function(){var g,I,C,A,Z,G,l,b,B,d=this,c=d.constructor,i=c.precision,m=c.rounding;if(d.isFinite()){if(d.isZero())return new c(d);if(d.abs().eq(1)&&i+4<=gl)return(l=gY(c,i+4,m).times(.25)).s=d.s,l}else{if(!d.s)return new c(NaN);if(i+4<=gl)return(l=gY(c,i+4,m).times(.5)).s=d.s,l}for(c.precision=b=i+10,c.rounding=1,g=C=Math.min(28,b/7+2|0);g;--g)d=d.div(d.times(d).plus(1).sqrt().plus(1));for(E=!1,I=Math.ceil(b/7),A=1,B=d.times(d),l=new c(d),Z=d;-1!==g;)if(Z=Z.times(B),G=l.minus(Z.div(A+=2)),Z=Z.times(B),void 0!==(l=G.plus(Z.div(A+=2))).d[I])for(g=I;l.d[g]===G.d[g]&&g--;);return C&&(l=l.times(2<this.d.length-2},gb.isNaN=function(){return!this.s},gb.isNegative=gb.isNeg=function(){return this.s<0},gb.isPositive=gb.isPos=function(){return this.s>0},gb.isZero=function(){return!!this.d&&0===this.d[0]},gb.lessThan=gb.lt=function(g){return 0>this.cmp(g)},gb.lessThanOrEqualTo=gb.lte=function(g){return 1>this.cmp(g)},gb.logarithm=gb.log=function(g){var I,C,A,Z,G,l,b,B=this.constructor,d=B.precision,c=B.rounding;if(null==g)g=new B(10),I=!0;else{if(C=(g=new B(g)).d,g.s<0||!C||!C[0]||g.eq(1))return new B(NaN);I=g.eq(10)}if(C=this.d,this.s<0||!C||!C[0]||this.eq(1))return new B(C&&!C[0]?-1/0:1!=this.s?NaN:C?0:1/0);if(I){if(C.length>1)Z=!0;else{for(A=C[0];A%10==0;)A/=10;Z=1!==A}}if(E=!1,gc((b=gm(gh(this,l=d+5),I?gV(B,l+10):gh(g,l),l,1)).d,A=d,c))do if(l+=10,b=gm(gh(this,l),I?gV(B,l+10):gh(g,l),l,1),!Z){+gB(b.d).slice(A+1,A+15)+1==1e14&&(b=gW(b,d+1,0));break}while(gc(b.d,A+=10,c));return E=!0,gW(b,d,c)},gb.minus=gb.sub=function(g){var I,C,A,Z,G,l,b,B,d,c,i,m,W=this.constructor;if(g=new W(g),!this.d||!g.d)return this.s&&g.s?this.d?g.s=-g.s:g=new W(g.d||this.s!==g.s?this:NaN):g=new W(NaN),g;if(this.s!=g.s)return g.s=-g.s,this.plus(g);if(d=this.d,m=g.d,b=W.precision,B=W.rounding,!d[0]||!m[0]){if(m[0])g.s=-g.s;else{if(!d[0])return new W(3===B?-0:0);g=new W(this)}return E?gW(g,b,B):g}if(C=$(g.e/7),c=$(this.e/7),d=d.slice(),G=c-C){for((i=G<0)?(I=d,G=-G,l=m.length):(I=m,C=c,l=d.length),G>(A=Math.max(Math.ceil(b/7),l)+2)&&(G=A,I.length=1),I.reverse(),A=G;A--;)I.push(0);I.reverse()}else{for((i=(A=d.length)<(l=m.length))&&(l=A),A=0;A0;--A)d[l++]=0;for(A=m.length;A>G;){if(d[--A](l=(G=Math.ceil(b/7))>l?G+1:l+1)&&(Z=l,C.length=1),C.reverse();Z--;)C.push(0);C.reverse()}for((l=d.length)-(Z=c.length)<0&&(Z=l,C=c,c=d,d=C),I=0;Z;)I=(d[--Z]=d[Z]+c[Z]+I)/1e7|0,d[Z]%=1e7;for(I&&(d.unshift(I),++A),l=d.length;0==d[--l];)d.pop();return g.d=d,g.e=gy(d,A),E?gW(g,b,B):g},gb.precision=gb.sd=function(g){var I;if(void 0!==g&&!!g!==g&&1!==g&&0!==g)throw Error(r+g);return this.d?(I=gH(this.d),g&&this.e+1>I&&(I=this.e+1)):I=NaN,I},gb.round=function(){var g=this.constructor;return gW(new g(this),this.e+1,g.rounding)},gb.sine=gb.sin=function(){var g,I,C=this,A=C.constructor;return C.isFinite()?C.isZero()?new A(C):(g=A.precision,I=A.rounding,A.precision=g+Math.max(C.e,C.sd())+7,A.rounding=1,C=function(g,I){var C,A=I.d.length;if(A<3)return I.isZero()?I:gu(g,2,I,I);C=(C=1.4*Math.sqrt(A))>16?16:0|C,I=gu(g,2,I=I.times(1/gp(5,C)),I);for(var Z,G=new g(5),l=new g(16),b=new g(20);C--;)Z=I.times(I),I=I.times(G.plus(Z.times(l.times(Z).minus(b))));return I}(A,gF(A,C)),A.precision=g,A.rounding=I,gW(z>2?C.neg():C,g,I,!0)):new A(NaN)},gb.squareRoot=gb.sqrt=function(){var g,I,C,A,Z,G,l=this.d,b=this.e,B=this.s,d=this.constructor;if(1!==B||!l||!l[0])return new d(!B||B<0&&(!l||l[0])?NaN:l?this:1/0);for(E=!1,0==(B=Math.sqrt(+this))||B==1/0?(((I=gB(l)).length+b)%2==0&&(I+="0"),B=Math.sqrt(I),b=$((b+1)/2)-(b<0||b%2),A=new d(I=B==1/0?"5e"+b:(I=B.toExponential()).slice(0,I.indexOf("e")+1)+b)):A=new d(B.toString()),C=(b=d.precision)+3;;)if(A=(G=A).plus(gm(this,G,C+2,1)).times(.5),gB(G.d).slice(0,C)===(I=gB(A.d)).slice(0,C)){if("9999"!=(I=I.slice(C-3,C+1))&&(Z||"4999"!=I)){+I&&(+I.slice(1)||"5"!=I.charAt(0))||(gW(A,b+1,1),g=!A.times(A).eq(this));break}if(!Z&&(gW(G,b+1,0),G.times(G).eq(this))){A=G;break}C+=4,Z=1}return E=!0,gW(A,b,d.rounding,g)},gb.tangent=gb.tan=function(){var g,I,C=this,A=C.constructor;return C.isFinite()?C.isZero()?new A(C):(g=A.precision,I=A.rounding,A.precision=g+10,A.rounding=1,(C=C.sin()).s=1,C=gm(C,new A(1).minus(C.times(C)).sqrt(),g+10,0),A.precision=g,A.rounding=I,gW(2==z||4==z?C.neg():C,g,I,!0)):new A(NaN)},gb.times=gb.mul=function(g){var I,C,A,Z,G,l,b,B,d,c=this.constructor,i=this.d,m=(g=new c(g)).d;if(g.s*=this.s,!i||!i[0]||!m||!m[0])return new c(g.s&&(!i||i[0]||m)&&(!m||m[0]||i)?i&&m?0*g.s:g.s/0:NaN);for(C=$(this.e/7)+$(g.e/7),(B=i.length)<(d=m.length)&&(G=i,i=m,m=G,l=B,B=d,d=l),G=[],A=l=B+d;A--;)G.push(0);for(A=d;--A>=0;){for(I=0,Z=B+A;Z>A;)b=G[Z]+m[A]*i[Z-A-1]+I,G[Z--]=b%1e7|0,I=b/1e7|0;G[Z]=(G[Z]+I)%1e7|0}for(;!G[--l];)G.pop();return I?++C:G.shift(),g.d=G,g.e=gy(G,C),E?gW(g,c.precision,c.rounding):g},gb.toBinary=function(g,I){return gw(this,2,g,I)},gb.toDecimalPlaces=gb.toDP=function(g,I){var C=this,A=C.constructor;return(C=new A(C),void 0===g)?C:(gd(g,0,1e9),void 0===I?I=A.rounding:gd(I,0,8),gW(C,g+C.e+1,I))},gb.toExponential=function(g,I){var C,A=this,Z=A.constructor;return void 0===g?C=go(A,!0):(gd(g,0,1e9),void 0===I?I=Z.rounding:gd(I,0,8),C=go(A=gW(new Z(A),g+1,I),!0,g+1)),A.isNeg()&&!A.isZero()?"-"+C:C},gb.toFixed=function(g,I){var C,A,Z=this.constructor;return void 0===g?C=go(this):(gd(g,0,1e9),void 0===I?I=Z.rounding:gd(I,0,8),C=go(A=gW(new Z(this),g+this.e+1,I),!1,g+A.e+1)),this.isNeg()&&!this.isZero()?"-"+C:C},gb.toFraction=function(g){var I,C,A,Z,G,l,b,B,d,c,i,m,W=this.d,o=this.constructor;if(!W)return new o(this);if(d=C=new o(1),A=B=new o(0),l=(G=(I=new o(A)).e=gH(W)-this.e-1)%7,I.d[0]=gg(10,l<0?7+l:l),null==g)g=G>0?I:d;else{if(!(b=new o(g)).isInt()||b.lt(d))throw Error(r+b);g=b.gt(I)?G>0?I:d:b}for(E=!1,b=new o(gB(W)),c=o.precision,o.precision=G=14*W.length;i=gm(b,I,0,1,1),1!=(Z=C.plus(i.times(A))).cmp(g);)C=A,A=Z,Z=d,d=B.plus(i.times(Z)),B=Z,Z=I,I=b.minus(i.times(Z)),b=Z;return Z=gm(g.minus(C),A,0,1,1),B=B.plus(Z.times(d)),C=C.plus(Z.times(A)),B.s=d.s=this.s,m=1>gm(d,A,G,1).minus(this).abs().cmp(gm(B,C,G,1).minus(this).abs())?[d,A]:[B,C],o.precision=c,E=!0,m},gb.toHexadecimal=gb.toHex=function(g,I){return gw(this,16,g,I)},gb.toNearest=function(g,I){var C=this,A=C.constructor;if(C=new A(C),null==g){if(!C.d)return C;g=new A(1),I=A.rounding}else{if(g=new A(g),void 0===I?I=A.rounding:gd(I,0,8),!C.d)return g.s?C:g;if(!g.d)return g.s&&(g.s=C.s),g}return g.d[0]?(E=!1,C=gm(C,g,0,I,1).times(g),E=!0,gW(C)):(g.s=C.s,C=g),C},gb.toNumber=function(){return+this},gb.toOctal=function(g,I){return gw(this,8,g,I)},gb.toPower=gb.pow=function(g){var I,C,A,Z,G,l,b=this,B=b.constructor,d=+(g=new B(g));if(!b.d||!g.d||!b.d[0]||!g.d[0])return new B(gg(+b,d));if((b=new B(b)).eq(1))return b;if(A=B.precision,G=B.rounding,g.eq(1))return gW(b,A,G);if((I=$(g.e/7))>=g.d.length-1&&(C=d<0?-d:d)<=9007199254740991)return Z=gK(B,b,C,A),g.s<0?new B(1).div(Z):gW(Z,A,G);if((l=b.s)<0){if(IB.maxE+1||I0?l/0:0):(E=!1,B.rounding=b.s=1,C=Math.min(12,(I+"").length),(Z=ga(g.times(gh(b,A+C)),A)).d&&gc((Z=gW(Z,A+5,1)).d,A,G)&&(I=A+10,+gB((Z=gW(ga(g.times(gh(b,I+C)),I),I+5,1)).d).slice(A+1,A+15)+1==1e14&&(Z=gW(Z,A+1,0))),Z.s=l,E=!0,B.rounding=G,gW(Z,A,G))},gb.toPrecision=function(g,I){var C,A=this,Z=A.constructor;return void 0===g?C=go(A,A.e<=Z.toExpNeg||A.e>=Z.toExpPos):(gd(g,1,1e9),void 0===I?I=Z.rounding:gd(I,0,8),C=go(A=gW(new Z(A),g,I),g<=A.e||A.e<=Z.toExpNeg,g)),A.isNeg()&&!A.isZero()?"-"+C:C},gb.toSignificantDigits=gb.toSD=function(g,I){var C=this.constructor;return void 0===g?(g=C.precision,I=C.rounding):(gd(g,1,1e9),void 0===I?I=C.rounding:gd(I,0,8)),gW(new C(this),g,I)},gb.toString=function(){var g=this.constructor,I=go(this,this.e<=g.toExpNeg||this.e>=g.toExpPos);return this.isNeg()&&!this.isZero()?"-"+I:I},gb.truncated=gb.trunc=function(){return gW(new this.constructor(this),this.e+1,1)},gb.valueOf=gb.toJSON=function(){var g=this.constructor,I=go(this,this.e<=g.toExpNeg||this.e>=g.toExpPos);return this.isNeg()?"-"+I:I};var gm=function(){function g(g,I,C){var A,Z=0,G=g.length;for(g=g.slice();G--;)A=g[G]*I+Z,g[G]=A%C|0,Z=A/C|0;return Z&&g.unshift(Z),g}function I(g,I,C,A){var Z,G;if(C!=A)G=C>A?1:-1;else for(Z=G=0;ZI[Z]?1:-1;break}return G}function C(g,I,C,A){for(var Z=0;C--;)g[C]-=Z,Z=g[C]1;)g.shift()}return function(A,Z,G,l,b,B){var d,c,i,m,W,o,y,V,Y,H,X,K,R,s,a,h,S,N,u,p,F=A.constructor,w=A.s==Z.s?1:-1,J=A.d,n=Z.d;if(!J||!J[0]||!n||!n[0])return new F(A.s&&Z.s&&(J?!n||J[0]!=n[0]:n)?J&&0==J[0]||!n?0*w:w/0:NaN);for(B?(W=1,c=A.e-Z.e):(B=1e7,W=7,c=$(A.e/W)-$(Z.e/W)),u=n.length,S=J.length,H=(Y=new F(w)).d=[],i=0;n[i]==(J[i]||0);i++);if(n[i]>(J[i]||0)&&c--,null==G?(s=G=F.precision,l=F.rounding):s=b?G+(A.e-Z.e)+1:G,s<0)H.push(1),o=!0;else{if(s=s/W+2|0,i=0,1==u){for(m=0,n=n[0],s++;(i1&&(n=g(n,m,B),J=g(J,m,B),u=n.length,S=J.length),h=u,K=(X=J.slice(0,u)).length;K=B/2&&++N;do m=0,(d=I(n,X,u,K))<0?(R=X[0],u!=K&&(R=R*B+(X[1]||0)),(m=R/N|0)>1?(m>=B&&(m=B-1),V=(y=g(n,m,B)).length,K=X.length,1==(d=I(y,X,V,K))&&(m--,C(y,u=10;m/=10)i++;Y.e=i+c*W-1,gW(Y,b?G+Y.e+1:G,l,o)}return Y}}();function gW(g,I,C,A){var Z,G,l,b,B,d,c,i,m,W=g.constructor;g:if(null!=I){if(!(i=g.d))return g;for(Z=1,b=i[0];b>=10;b/=10)Z++;if((G=I-Z)<0)G+=7,l=I,B=(c=i[m=0])/gg(10,Z-l-1)%10|0;else if((m=Math.ceil((G+1)/7))>=(b=i.length)){if(A){for(;b++<=m;)i.push(0);c=B=0,Z=1,G%=7,l=G-7+1}else break g}else{for(Z=1,c=b=i[m];b>=10;b/=10)Z++;G%=7,B=(l=G-7+Z)<0?0:c/gg(10,Z-l-1)%10|0}if(A=A||I<0||void 0!==i[m+1]||(l<0?c:c%gg(10,Z-l-1)),d=C<4?(B||A)&&(0==C||C==(g.s<0?3:2)):B>5||5==B&&(4==C||A||6==C&&(G>0?l>0?c/gg(10,Z-l):0:i[m-1])%10&1||C==(g.s<0?8:7)),I<1||!i[0])return i.length=0,d?(I-=g.e+1,i[0]=gg(10,(7-I%7)%7),g.e=-I||0):i[0]=g.e=0,g;if(0==G?(i.length=m,b=1,m--):(i.length=m+1,b=gg(10,7-G),i[m]=l>0?(c/gg(10,Z-l)%gg(10,l)|0)*b:0),d)for(;;){if(0==m){for(G=1,l=i[0];l>=10;l/=10)G++;for(l=i[0]+=b,b=1;l>=10;l/=10)b++;G!=b&&(g.e++,1e7==i[0]&&(i[0]=1));break}if(i[m]+=b,1e7!=i[m])break;i[m--]=0,b=1}for(G=i.length;0===i[--G];)i.pop()}return E&&(g.e>W.maxE?(g.d=null,g.e=NaN):g.e0?G=G.charAt(0)+"."+G.slice(1)+gX(A):l>1&&(G=G.charAt(0)+"."+G.slice(1)),G=G+(g.e<0?"e":"e+")+g.e):Z<0?(G="0."+gX(-Z-1)+G,C&&(A=C-l)>0&&(G+=gX(A))):Z>=l?(G+=gX(Z+1-l),C&&(A=C-Z-1)>0&&(G=G+"."+gX(A))):((A=Z+1)0&&(Z+1===l&&(G+="."),G+=gX(A))),G}function gy(g,I){var C=g[0];for(I*=7;C>=10;C/=10)I++;return I}function gV(g,I,C){if(I>gG)throw E=!0,C&&(g.precision=C),Error(f);return gW(new g(P),I,1,!0)}function gY(g,I,C){if(I>gl)throw Error(f);return gW(new g(x),I,C,!0)}function gH(g){var I=g.length-1,C=7*I+1;if(I=g[I]){for(;I%10==0;I/=10)C--;for(I=g[0];I>=10;I/=10)C++}return C}function gX(g){for(var I="";g--;)I+="0";return I}function gK(g,I,C,A){var Z,G=new g(1),l=Math.ceil(A/7+4);for(E=!1;;){if(C%2&&gJ((G=G.times(I)).d,l)&&(Z=!0),0===(C=$(C/2))){C=G.d.length-1,Z&&0===G.d[C]&&++G.d[C];break}gJ((I=I.times(I)).d,l)}return E=!0,G}function gR(g){return 1&g.d[g.d.length-1]}function gs(g,I,C){for(var A,Z,G=new g(I[0]),l=0;++l17)return new m(g.d?g.d[0]?g.s<0?0:1/0:1:g.s?g.s<0?0:g:0/0);for(null==I?(E=!1,B=o):B=I,b=new m(.03125);g.e>-2;)g=g.times(b),i+=5;for(B+=A=Math.log(gg(2,i))/Math.LN10*2+5|0,C=G=l=new m(1),m.precision=B;;){if(G=gW(G.times(g),B,1),C=C.times(++c),gB((b=l.plus(gm(G,C,B,1))).d).slice(0,B)===gB(l.d).slice(0,B)){for(Z=i;Z--;)l=gW(l.times(l),B,1);if(null!=I)return m.precision=o,l;if(!(d<3&&gc(l.d,B-A,W,d)))return gW(l,m.precision=o,W,E=!0);m.precision=B+=10,C=G=b=new m(1),c=0,d++}l=b}}function gh(g,I){var C,A,Z,G,l,b,B,d,c,i,m,W=1,o=g,y=o.d,V=o.constructor,Y=V.rounding,H=V.precision;if(o.s<0||!y||!y[0]||!o.e&&1==y[0]&&1==y.length)return new V(y&&!y[0]?-1/0:1!=o.s?NaN:y?0:o);if(null==I?(E=!1,c=H):c=I,V.precision=c+=10,A=(C=gB(y)).charAt(0),!(15e14>Math.abs(G=o.e)))return d=gV(V,c+2,H).times(G+""),o=gh(new V(A+"."+C.slice(1)),c-10).plus(d),V.precision=H,null==I?gW(o,H,Y,E=!0):o;for(;A<7&&1!=A||1==A&&C.charAt(1)>3;)A=(C=gB((o=o.times(g)).d)).charAt(0),W++;for(G=o.e,A>1?(o=new V("0."+C),G++):o=new V(A+"."+C.slice(1)),i=o,B=l=o=gm(o.minus(1),o.plus(1),c,1),m=gW(o.times(o),c,1),Z=3;;){if(l=gW(l.times(m),c,1),gB((d=B.plus(gm(l,new V(Z),c,1))).d).slice(0,c)===gB(B.d).slice(0,c)){if(B=B.times(2),0!==G&&(B=B.plus(gV(V,c+2,H).times(G+""))),B=gm(B,new V(W),c,1),null!=I)return V.precision=H,B;if(!gc(B.d,c-10,Y,b))return gW(B,V.precision=H,Y,E=!0);V.precision=c+=10,d=l=o=gm(i.minus(1),i.plus(1),c,1),m=gW(o.times(o),c,1),Z=b=1}B=d,Z+=2}}function gS(g){return String(g.s*g.s/0)}function gN(g,I){var C,A,Z;for((C=I.indexOf("."))>-1&&(I=I.replace(".","")),(A=I.search(/e/i))>0?(C<0&&(C=A),C+=+I.slice(A+1),I=I.substring(0,A)):C<0&&(C=I.length),A=0;48===I.charCodeAt(A);A++);for(Z=I.length;48===I.charCodeAt(Z-1);--Z);if(I=I.slice(A,Z)){if(Z-=A,g.e=C=C-A-1,g.d=[],A=(C+1)%7,C<0&&(A+=7),Ag.constructor.maxE?(g.d=null,g.e=NaN):g.e=0&&(c=c.replace(".",""),(m=new W(1)).e=c.length-l,m.d=gi(go(m),10,Z),m.e=m.d.length),G=B=(i=gi(c,10,Z)).length;0==i[--B];)i.pop();if(i[0]){if(l<0?G--:((g=new W(g)).d=i,g.e=G,i=(g=gm(g,m,C,A,0,Z)).d,G=g.e,d=Q),l=i[C],b=Z/2,d=d||void 0!==i[C+1],d=A<4?(void 0!==l||d)&&(0===A||A===(g.s<0?3:2)):l>b||l===b&&(4===A||d||6===A&&1&i[C-1]||A===(g.s<0?8:7)),i.length=C,d)for(;++i[--C]>Z-1;)i[C]=0,C||(++G,i.unshift(1));for(B=i.length;!i[B-1];--B);for(l=0,c="";l1){if(16==I||8==I){for(l=16==I?4:3,--B;B%l;B++)c+="0";for(B=(i=gi(c,Z,I)).length;!i[B-1];--B);for(l=1,c="1.";lB)for(G-=B;G--;)c+="0";else GI)return g.length=I,!0}function gn(g){return new this(g).abs()}function gD(g){return new this(g).acos()}function gv(g){return new this(g).acosh()}function gk(g,I){return new this(g).plus(I)}function gQ(g){return new this(g).asin()}function gz(g){return new this(g).asinh()}function gL(g){return new this(g).atan()}function gT(g){return new this(g).atanh()}function gU(g,I){g=new this(g),I=new this(I);var C,A=this.precision,Z=this.rounding,G=A+4;return g.s&&I.s?g.d||I.d?!I.d||g.isZero()?(C=I.s<0?gY(this,A,Z):new this(0)).s=g.s:!g.d||I.isZero()?(C=gY(this,G,1).times(.5)).s=g.s:I.s<0?(this.precision=G,this.rounding=1,C=this.atan(gm(g,I,G,1)),I=gY(this,G,1),this.precision=A,this.rounding=Z,C=g.s<0?C.minus(I):C.plus(I)):C=this.atan(gm(g,I,G,1)):(C=gY(this,G,1).times(I.s>0?.25:.75)).s=g.s:C=new this(NaN),C}function gM(g){return new this(g).cbrt()}function gt(g){return gW(g=new this(g),g.e+1,2)}function ge(g,I,C){return new this(g).clamp(I,C)}function gP(g){if(!g||"object"!=typeof g)throw Error(O+"Object expected");var I,C,A,Z=!0===g.defaults,G=["precision",1,1e9,"rounding",0,8,"toExpNeg",-9e15,0,"toExpPos",0,9e15,"maxE",0,9e15,"minE",-9e15,0,"modulo",0,9];for(I=0;I=G[I+1]&&A<=G[I+2])this[C]=A;else throw Error(r+C+": "+A)}if(C="crypto",Z&&(this[C]=j[C]),void 0!==(A=g[C])){if(!0===A||!1===A||0===A||1===A){if(A){if("undefined"!=typeof crypto&&crypto&&(crypto.getRandomValues||crypto.randomBytes))this[C]=!0;else throw Error(q)}else this[C]=!1}else throw Error(r+C+": "+A)}return this}function gx(g){return new this(g).cos()}function gj(g){return new this(g).cosh()}function gE(g,I){return new this(g).div(I)}function gO(g){return new this(g).exp()}function gr(g){return gW(g=new this(g),g.e+1,3)}function gf(){var g,I,C=new this(0);for(g=0,E=!1;g=429e7?I[G]=crypto.getRandomValues(new Uint32Array(1))[0]:b[G++]=Z%1e7;else if(crypto.randomBytes){for(I=crypto.randomBytes(A*=4);G=214e7?crypto.randomBytes(4).copy(I,G):(b.push(Z%1e7),G+=4);G=A/4}else throw Error(q)}else for(;G=10;Z/=10)A++;A<7&&(C-=7-A)}return l.e=C,l.d=b,l}function g7(g){return gW(g=new this(g),g.e+1,this.rounding)}function g6(g){return(g=new this(g)).d?g.d[0]?g.s:0*g.s:g.s||NaN}function Ig(g){return new this(g).sin()}function II(g){return new this(g).sinh()}function IC(g){return new this(g).sqrt()}function IA(g,I){return new this(g).sub(I)}function IZ(){var g=0,I=arguments,C=new this(I[0]);for(E=!1;C.s&&++gG.maxE?(this.e=NaN,this.d=null):g.e=10;C/=10)I++;E?I>G.maxE?(this.e=NaN,this.d=null):I-1){if(I=I.replace(/(\d)_(?=\d)/g,"$1"),gZ.test(I))return gN(g,I)}else if("Infinity"===I||"NaN"===I)return+I||(g.s=NaN),g.e=NaN,g.d=null,g;if(gC.test(I))C=16,I=I.toLowerCase();else if(gI.test(I))C=2;else if(gA.test(I))C=8;else throw Error(r+I);for((G=I.search(/p/i))>0?(B=+I.slice(G+1),I=I.substring(2,G)):I=I.slice(2),l=(G=I.indexOf("."))>=0,A=g.constructor,l&&(G=(b=(I=I.replace(".","")).length)-G,Z=gK(A,new A(C),G,2*G)),G=c=(d=gi(I,C,1e7)).length-1;0===d[G];--G)d.pop();return G<0?new A(0*g.s):(g.e=gy(d,c),g.d=d,E=!1,l&&(g=gm(g,Z,4*b)),B&&(g=g.times(54>Math.abs(B)?gg(2,B):IB.pow(2,B))),E=!0,g)}(this,g);if("bigint"===A)return g<0?(g=-g,this.s=-1):this.s=1,gN(this,g.toString());throw Error(r+g)}if(G.prototype=gb,G.ROUND_UP=0,G.ROUND_DOWN=1,G.ROUND_CEIL=2,G.ROUND_FLOOR=3,G.ROUND_HALF_UP=4,G.ROUND_HALF_DOWN=5,G.ROUND_HALF_EVEN=6,G.ROUND_HALF_CEIL=7,G.ROUND_HALF_FLOOR=8,G.EUCLID=9,G.config=G.set=gP,G.clone=g,G.isDecimal=gq,G.abs=gn,G.acos=gD,G.acosh=gv,G.add=gk,G.asin=gQ,G.asinh=gz,G.atan=gL,G.atanh=gT,G.atan2=gU,G.cbrt=gM,G.ceil=gt,G.clamp=ge,G.cos=gx,G.cosh=gj,G.div=gE,G.exp=gO,G.floor=gr,G.hypot=gf,G.ln=g_,G.log=g$,G.log10=g9,G.log2=g0,G.max=g2,G.min=g5,G.mod=g3,G.mul=g1,G.pow=g4,G.random=g8,G.round=g7,G.sign=g6,G.sin=Ig,G.sinh=II,G.sqrt=IC,G.sub=IA,G.sum=IZ,G.tan=IG,G.tanh=Il,G.trunc=Ib,void 0===I&&(I={}),I&&!0!==I.defaults)for(C=0,Z=["precision","rounding","toExpNeg","toExpPos","maxE","minE","modulo","crypto"];C0){var I=document.cookie.indexOf("".concat(g,"="));if(-1!=I){I=I+g.length+1;var C=document.cookie.indexOf(";",I);return -1==C&&(C=document.cookie.length),decodeURIComponent(document.cookie.substring(I,C))}}return""},IY=function(){var g,C;function A(g){var C=this,G=g.host,b=g.autoConnect,B=g.useOriginalData,d=g.showLog,c=void 0!==d&&d;if(!function(g,I){if(!(g instanceof I))throw TypeError("Cannot call a class as a function")}(this,A),l(this,"worker",void 0),l(this,"autoConnect",void 0),l(this,"showLog",void 0),l(this,"useOriginalData",void 0),l(this,"wsUrl",void 0),l(this,"allSymbolQuoteSubject",new M({})),l(this,"fsAllSymbolQuoteSubject",new M({})),l(this,"timeCoinSymbolNotifySubject",new M({})),l(this,"calcEstimateSlippageSubject",new M({})),l(this,"instrumentSubject",new M({})),l(this,"fsInstrumentSubject",new M({})),l(this,"marketCandleSubject",new M({})),l(this,"markCandleAllSubject",new M({})),l(this,"indexQuoteSubject",new M({})),l(this,"orderBookSubject",new M({})),l(this,"fsOrderBookSubject",new M({})),l(this,"optionOrderBookSubject",new M({})),l(this,"mt5OrderBookSubject",new M({})),l(this,"mt5TickersAllSubject",new M({})),l(this,"alphaTickersAllSubject",new M({})),l(this,"mt5klineSubject",new M({})),l(this,"recentTradeSubject",new M({})),l(this,"fsRecentTradeSubject",new M({})),l(this,"publicNoticeSubject",new M({})),l(this,"websocketEventSubject",new M({})),l(this,"wsEventCb",function(g,I){C.websocketEventSubject.next({type:g,data:I})}),l(this,"connect",function(){C.worker.postMessage({action:"INIT",payload:{url:C.wsUrl,useOriginalData:C.useOriginalData,showLog:C.showLog}})}),l(this,"changeUrl",function(g){C.wsUrl="".concat(g).concat(Z),C.worker.postMessage({action:"CHANGE_URL",payload:{url:C.wsUrl,autoConnect:C.autoConnect,useOriginalData:C.useOriginalData,showLog:C.showLog}})}),l(this,"subscribeTopic",function(g){var A=g.topic,Z=g.symbol,G=g.minutes,l=g.obParams,b=g.mt5TickersAllParams,B=g.publicParams,d=g.throttleTime,c=Z?"".concat(A).concat(Z):A;if(A===I.DI.OrderBook){var i=l.ratio,m=l.level;c="".concat(A).concat(m,"@m").concat(i,".H.").concat(Z)}else if(A===I.$H.OrderBook||A===I.o_.OrderBook){var W=l.level;c="".concat(A).concat(W,".").concat(Z)}else A===I.DI.MT5OrderBook?c="".concat(A,"5.").concat(Z):A===I.DI.MT5Kline&&(c="".concat(A).concat(G,".").concat(Z));if(Z)try{A===I.DI.OrderBook&&Ic(Z),A===I.$H.OrderBook&&Im(Z),A===I.o_.OrderBook&&Io(Z),A===I.DI.MT5OrderBook&&Iy(Z)}catch(g){console.warn("symbolOBCancel: ".concat(g))}C.worker.postMessage({action:"SUBSCRIBE",payload:{topic:A,realTopic:c,mt5TickersAllParams:b,publicParams:B,nameSpace:Z||"",obParams:l,throttleTime:d}})}),l(this,"unsubscribeTopic",function(g){var A=g.topic,Z=g.symbol,G=g.minutes,l=g.obParams,b=Z?"".concat(A).concat(Z):A;if(A===I.DI.OrderBook){var B=l.ratio,d=l.level;b="".concat(A).concat(d,"@m").concat(B,".H.").concat(Z)}else if(A===I.$H.OrderBook||A===I.o_.OrderBook){var c=l.level;b="".concat(A).concat(c,".").concat(Z)}else A===I.DI.MT5OrderBook?b="".concat(A,"5.").concat(Z):A===I.DI.MT5Kline&&(b="".concat(A).concat(G,".").concat(Z));C.worker.postMessage({action:"UNSUBSCRIBE",payload:{realTopic:b}})}),l(this,"subscribeTopicDirect",function(g,I){C.worker.postMessage({action:"SUBSCRIBE_DIRECT",payload:{topic:I,realTopic:g,nameSpace:g}})}),l(this,"unsubscribeTopicDirect",function(g){var I=!(arguments.length>1)||void 0===arguments[1]||arguments[1];I&&(g.startsWith("candle")?C.marketCandleSubject.next({}):C.markCandleAllSubject.next({})),C.worker.postMessage({action:"UNSUBSCRIBE_DIRECT",payload:{realTopic:g}})}),l(this,"sendToWorker",function(g,I){C.worker.postMessage({action:"SAVE_DATA",payload:{dataName:g,data:I}})}),this.autoConnect=void 0===b||b,this.useOriginalData=void 0!==B&&B,"undefined"==typeof window&&!G)throw Error("need to host param");if(this.wsUrl="".concat(G).concat(Z)||"".concat(window.origin).concat(Z),"DedicatedWorkerGlobalScope"===globalThis.constructor.name)this.showLog=c;else{var i=IV("fbu.public.ws.log");this.showLog=i||c}this.worker=new t,this.worker.onmessage=function(g){var A=g.data||{},Z=A.type,G=A.topic,l=A.data;if([I.jH.CONNECT,I.jH.RECONNECT,I.jH.CLOSE,I.jH.OPEN_ERROR,I.jH.HEART_ERROR,I.jH.HEART_BACK,I.jH.RECONNECT_FAILED,I.jH.RECONNECT_START].includes(Z)&&C.wsEventCb(Z,l),"UPDATE_DATE"===Z)switch(G){case I.DI.InstrumentInfo_H:case I.DI.InstrumentInfo_M:C.instrumentSubject.next(l);break;case I.DI.OrderBook:C.orderBookSubject.next(l);break;case I.DI.RecentTrade:C.recentTradeSubject.next(l);break;case I.DI.InstrumentInfoAll:C.allSymbolQuoteSubject.next(l);break;case I.DI.TimeCoinSymbolNotify:C.timeCoinSymbolNotifySubject.next(l);break;case"calcEstimateSlippage":C.calcEstimateSlippageSubject.next(l);break;case I.DI.PublicNotice:C.publicNoticeSubject.next(l);break;case I.lB.MARKET_CANDLE:C.marketCandleSubject.next(l);break;case I.lB.MARK_CANDLE:C.markCandleAllSubject.next(l);break;case I.$H.OrderBook:C.fsOrderBookSubject.next(l);break;case I.o_.OrderBook:C.optionOrderBookSubject.next(l);break;case I.DI.MT5OrderBook:C.mt5OrderBookSubject.next(l);break;case I.$H.InstrumentInfo:C.fsInstrumentSubject.next(l);break;case I.$H.InstrumentInfoAll:C.fsAllSymbolQuoteSubject.next(l);break;case I.DI.AlphaTickersAll:C.alphaTickersAllSubject.next(l);break;case I.$H.RecentTrade:C.fsRecentTradeSubject.next(l);break;case I.DI.MT5TickersAll:C.mt5TickersAllSubject.next(l);break;case I.DI.MT5Kline:C.mt5klineSubject.next(l);break;default:console.warn("ByFbuPublicWs: topic type not support =>",G)}},this.autoConnect&&this.connect()}return g=[{key:"setPageActive",value:function(g){this.worker.postMessage({action:"PAGE_ACTIVE_CHANGE",payload:{isActive:g}})}},{key:"updateFutureOpenPriceList",value:function(g){this.worker.postMessage({action:"UPDATE_FUTURE_OPEN_PRICE_LIST",payload:{openPriceList:g}})}}],C=[{key:"getInstance",value:function(g){if(!A.publicWsInstance){if(!g)throw Error("ByTradePublicWs not initialized. Please call getInstance(config) first.");A.publicWsInstance=new A(g)}return A.publicWsInstance}},{key:"resetInstance",value:function(g){if(A.publicWsInstance){console.warn("[ByTradePublicWs] Resetting WebSocket instance...");try{var I;null===(I=A.publicWsInstance.worker)||void 0===I||I.terminate()}catch(g){console.error("Failed to terminate existing worker:",g)}A.publicWsInstance=null}if(!g)throw Error("resetInstance() requires config to rebuild the instance.");return A.publicWsInstance=new A(g),A.publicWsInstance}}],g&&G(A.prototype,g),C&&G(A,C),Object.defineProperty(A,"prototype",{writable:!1}),A}();l(IY,"publicWsInstance",null),I.ZP=IY}}]); //# sourceMappingURL=1307a9ab-155a0feca91e394a.js.map